我对某些#define
陈述感到困惑.在图书馆中,它们似乎是跨越不同文件的通信手段,具有大量的#ifdef
s和#ifndef
s.
话虽如此,我现在有两个文件,file1.c
并file2.c
与#define TEST 10
内部编译在一起file2.c
.然而,当我TEST
在file2.c
编译器内部使用时,会出现以下错误消息:
'TEST' undeclared (first use in this function)
Run Code Online (Sandbox Code Playgroud)
#define
指令是否全球化?
MBy*_*ByD 18
#define
s不是全局的,它们只是在使用它们时的替代(如果在同一个编译单元中声明)
它们不是全局变量,它们不是符号,它们在链接时无关紧要,它们仅与预编译有关.
#define
d宏是全局的,因为它们不遵循正常的C作用域规则.宏的文本替换将(几乎)应用于宏名称后面的任何位置#define
.(值得注意的例外是宏名称是注释的一部分还是字符串文字的一部分.)
如果在头文件中定义一个宏,#include
那个头文件的任何文件都将继承该宏(无论它们是否需要它),除非它们明确地取消它#undef
.
在您的示例中,file2.c
不了解TEST
宏.它怎么会知道拿起#define
从file1.c
?通过魔术?由于宏在源代码上执行文本替换,因此在生成的目标文件中不存在它们的表示.file2.c
因此需要知道替换规则本身,如果您希望跨多个文件共享,则#define
需要存在于您的.c
文件的公共头文件中#include
.
如果您具体询问#ifdef
在库中看到的s数量有多少,那么很多都可能会检查编译环境提供的预定义宏名称.例如,C99编译器定义了一个__STDC_VERSION__
指定语言版本的宏; Microsoft编译器定义_MSC_VER
宏.大多数编译器还允许将简单宏定义为命令行参数.例如,您可以编译代码通过gcc -DNDEBUG file1.c
编译file.c
与NDEBUG
定义为禁用assert
秒.