一个由__GNUC__引起的编译问题

来源:互联网 发布:path finder mac 编辑:程序博客网 时间:2024/04/30 11:17
    在前一阵的项目集成过程中遇到一个__GNUC__引起的编译问题,记录下来。

    开发平台是linux + oracle proc + database,在编译过程中遇到一个编译错误,报错如下:

...................../ecitype.hPCC-S-02201, Encountered the symbol "aciub8" when expecting one of the following:; , = ( [The symbol ";"
    这个错误是oracle proc报的错误,乍看让人摸不着头脑。观察错误信息,应该是在对ecitype.h的预处理过程中出现了错误,仔细查看该文件发现报错点symbol "aciub8"在下面代码附近:

#ifndef __GNUC__typedef unsigned _int64 aciub8;typedef signed _int64 acisb8;#elsetypedef unsigned long long aciub8;typedef signed long long acisb8;#endif
    这是一个条件编译,如果是Linux平台就用 long long 类型表示8字节类型,如果是其他平台则用_int64表示。
    把项目中的代码进行简化成一个单独的c文件,编译并不报错。把宏定义注释掉,直接改成下面代码则编译通过。

//#ifndef __GNUC__//typedef unsigned _int64 aciub8;//typedef signed _int64 acisb8;//#elsetypedef unsigned long long aciub8;typedef signed long long acisb8;//#endif

    看来问题出现在宏定义上。原来_int64这个数据类型是windows下支持的,linux下面没有_int64这个数据类型。

    为什么在简化版本中并不报错呢?应该是现场环境下的__GNUC__没有起到作用。__GNUC__是linux内置的一个宏,其说明如下:

__GNUC__  __GNUC_MINOR__  __GNUC_PATCHLEVEL__  These macros are defined by all GNU compilers that use the C preprocessor: C, C++, and Objective-C. Their values are the major version, minor version, and patch level of the compiler, as integer constants. For example, GCC 3.2.1 will define __GNUC__ to 3, __GNUC_MINOR__ to 2, and __GNUC_PATCHLEVEL__ to 1.They are defined only when the entire compiler is in use; if you invoke the preprocessor directly, they are not defined.__GNUC_PATCHLEVEL__ is new to GCC 3.0; it is also present in the widely-used development snapshots leading up to 3.0 (which identify themselves as GCC 2.96 or 2.97,depending on which snapshot you have).     If all you need to know is whether or not your program is being compiled by GCC, you can simply test __GNUC__. If you need to write code which depends on a specific version, you must be more careful. Each time the minor version is increased, the patch level is reset to zero; each time the major version is increased (which happens rarely), the minor version and patch level are reset. If you wish to use the predefined macros directly in the conditional, youwill need to write it like this:               /* Test for GCC > 3.2.0 */            #if __GNUC__ > 3 || \                (__GNUC__ == 3 && (__GNUC_MINOR__ > 2 || \                                   (__GNUC_MINOR__ == 2 && \                                    __GNUC_PATCHLEVEL__ > 0))         Another approach is to use the predefined macros to calculate a single number, then compare that against a threshold:               #define GCC_VERSION (__GNUC__ * 10000 \                                 + __GNUC_MINOR__ * 100 \                                 + __GNUC_PATCHLEVEL__)            ...            /* Test for GCC > 3.2.0 */            #if GCC_VERSION > 30200         Many people find this form easier to understand.   

    由于现场环境中存在oracle proc预编译环境,符合说明中的第二条“if you invoke the preprocessor directly, they are not defined.”,所以并没有起到作用,在makefile里显示把宏开启 -D__GNUC__ 编译通过。

原创粉丝点击