3.7.2 常见预定义宏
常见的预定义宏是GNU C的扩展。无论您是在哪种机器或操作系统上使用GNU C或GNU Fortran,它们都具有相同的含义。它们的名字都以双下划线开头。
-
__COUNTER__
这个宏展开为从0开始的连续整数值。与##操作符结合使用,可以提供一种生成唯一标识符的便捷方法。需要注意确保在包含可能使用__COUNTER__的预编译头之前不要提前展开它。否则,预编译头将不会被使用。
-
__GFORTRAN__
GNU Fortran编译器定义了这个宏。
-
__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__
所有使用C预处理器的GNU编译器(包括C、C++、Objective-C和Fortran)都会定义这些宏。它们的值分别是编译器的主要版本号、次要版本号和修订版本号,作为整数常量。例如,GCC版本x.y.z会将__GNUC__定义为x,__GNUC_MINOR__定义为y,__GNUC_PATCHLEVEL__定义为z。如果直接调用预处理器,这些宏也会被定义。
如果你只需要知道你的程序是否由GCC编译,或者由声称接受GNU C方言的非GCC编译器编译,你可以简单地测试__GNUC__。如果你需要编写依赖于特定版本的代码,则需要更加谨慎。每次次版本号增加时,修订版本会被重置为零;每次主版本号增加时,次版本号和修订版本都被重置。如果你想在条件语句中直接使用预定义的宏,你需要这样写:
/* 测试GCC > 3.2.0 */
#if __GNUC__ > 3 || \
(__GNUC__ == 3 && (__GNUC_MINOR__ > 2 || \
(__GNUC_MINOR__ == 2 && \
__GNUC_PATCHLEVEL__ > 0)))
另一种方法是使用预定义的宏计算一个数字,然后对比阈值:
#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
...
/* 测试GCC > 3.2.0 */
#if GCC_VERSION > 30200
许多人发现这种形式更容易理解。
-
__GNUG__
GNU C++编译器定义了这个宏。测试它等同于测试(__GNUC__ && __cplusplus)。
-
__STRICT_ANSI__
当GCC被调用时,如果指定了-ansi开关,或指定了严格符合某个ISO C或ISO C++版本的-std开关,则GCC定义此宏,并将其定义为‘1’。此宏主要目的是指导GNU libc的头文件仅使用标准C中的定义。
-
__BASE_FILE__
这个宏展开为主输入文件的名称,形式为C字符串常量。这是在预处理器或C编译器命令行上指定的源文件。
-
__FILE_NAME__
这个宏展开为当前输入文件的基本名称,形式为C字符串常量。这是预处理器打开文件时使用的路径的最后一部分。例如,处理"/usr/local/include/myheader.h"会将此宏设置为"myheader.h"。
-
__INCLUDE_LEVEL__
这个宏展开为代表包含文件嵌套深度的十进制整数常量。每当遇到‘#include’指令时,该宏的值加一;每当你离开一个包含文件时,其值减一。它从0开始,在命令行指定的基础文件中。
-
__ELF__
如果目标使用ELF对象格式,则定义此宏。
-
__VERSION__
这个宏展开为描述正在使用的编译器版本的字符串常量。你不应该依赖它的内容具有任何特定的形式,但它至少会包含发行编号。
-
__OPTIMIZE____OPTIMIZE_SIZE____NO_INLINE__
这些宏描述了编译模式:
__OPTIMIZE__在所有优化编译中定义此宏。__OPTIMIZE_SIZE__如果编译器正在针对代码大小而非速度进行优化,则定义此宏。__NO_INLINE__如果没有函数会被内联到它们的调用者(当不进行优化,或者通过-fno-inline特别禁用了内联时),则定义此宏。
这些宏使得某些GNU头文件能够使用宏或内联函数提供系统库函数的优化定义。除非你确保程序在这些宏被定义与否的情况下执行效果相同,否则你不应该以任何方式使用这些宏。如果它们被定义了,它们的值为1。
-
__GNUC_GNU_INLINE__
如果声明为 inline 的函数将按照GCC传统的 gnu90 模式处理,则GCC定义这个宏。目标文件将包含所有声明为 inline 而没有 extern 或 static 修饰符的函数的外部可见定义。它不会包含任何声明为 extern inline 的函数的定义。
-
__GNUC_STDC_INLINE__
如果声明为 inline 的函数将根据 ISO C99 或更新的标准处理,则GCC定义这个宏。目标文件将包含所有声明为 extern inline 的函数的外部可见定义。它不会包含任何声明为 inline 而没有 extern 修饰符的函数的定义。
如果定义了这个宏,GCC 支持使用 gnu_inline 函数属性,以此来始终实现 gnu90 模式的行为。
__CHAR_UNSIGNED__
当且仅当目标机器上的 char 数据类型为无符号类型时,GCC 会定义这个宏。它的存在是为了让标准头文件 limits.h 能正常工作。你不应直接使用这个宏,而应参考 limits.h 里定义的标准宏。
__WCHAR_UNSIGNED__
类似于 __CHAR_UNSIGNED__,此宏仅在数据类型 wchar_t 是无符号类型且前端处于 C++ 模式时定义。
__REGISTER_PREFIX__
此宏展开为一个单一的标记(不是字符串常量),表示目标平台汇编语言中用于 CPU 寄存器名称的前缀。你可以使用它编写适用于多种环境的汇编代码。例如:
- 在
m68k-aout环境中,它展开为空。 - 在
m68k-coff环境中,它展开为单个字符%。
__USER_LABEL_PREFIX__
此宏展开为一个单一的标记,表示在汇编中应用于用户标签(对 C 代码可见的符号)的前缀。例如:
- 在
m68k-aout环境中,它展开为_。 - 在
m68k-coff环境中,它展开为空。
即使使用了 -f(no-)underscores 选项,此宏仍然会有正确的定义;但如果使用了调整此前缀的目标特定选项(例如 OSF/rose 的 -mno-underscores 选项),它的值可能不正确。
__SIZE_TYPE__
__PTRDIFF_TYPE__
__WCHAR_TYPE__
__WINT_TYPE__
__INTMAX_TYPE__
<

最低0.47元/天 解锁文章
262

被折叠的 条评论
为什么被折叠?



