C:#define指令是否全局?

Ran*_*lue 14 c

我对某些#define陈述感到困惑.在图书馆中,它们似乎是跨越不同文件的通信手段,具有大量的#ifdefs和#ifndefs.

话虽如此,我现在有两个文件,file1.cfile2.c#define TEST 10内部编译在一起file2.c.然而,当我TESTfile2.c编译器内部使用时,会出现以下错误消息:

'TEST' undeclared (first use in this function)
Run Code Online (Sandbox Code Playgroud)

#define指令是否全球化?

MBy*_*ByD 18

#defines不是全局的,它们只是在使用它们时的替代(如果在同一个编译单元中声明)

它们不是全局变量,它们不是符号,它们在链接时无关紧要,它们仅与预编译有关.

  • 基本上 - 不.如果要在它们之间共享宏,请将其放在头文件中并在两个文件中包含该标头. (4认同)
  • “编译单元”是什么意思?如何在同一个编译单元中包含“file1.c”和“file.2”? (2认同)
  • 不,它们是单独编译的。和母鸡连在一起。您熟悉 C 构建过程吗? (2认同)
  • @Randomblue:将“编译单元”视为“ac 文件,以及它包含的所有头文件,以及包含的所有头文件,等等,等等,直到没有更多头文件”。这是编译器编译的一个“块”。编译器分别编译每个 c 文件后,将这些输出链接在一起。 (2认同)

jam*_*lin 9

#defined宏是全局的,因为它们不遵循正常的C作用域规则.宏的文本替换将(几乎)应用于宏名称后面的任何位置#define.(值得注意的例外是宏名称是注释的一部分还是字符串文字的一部分.)

如果在头文件中定义一个宏,#include那个头文件的任何文件都将继承该宏(无论它们是否需要它),除非它们明确地取消它#undef.

在您的示例中,file2.c不了解TEST宏.它怎么会知道拿起#definefile1.c?通过魔术?由于宏在源代码上执行文本替换,因此在生成的目标文件中不存在它们的表示.file2.c因此需要知道替换规则本身,如果您希望跨多个文件共享,则#define需要存在于您的.c文件的公共头文件中#include.

如果您具体询问#ifdef在库中看到的s数量有多少,那么很多都可能会检查编译环境提供的预定义宏名称.例如,C99编译器定义了一个__STDC_VERSION__指定语言版本的宏; Microsoft编译器定义_MSC_VER宏.大多数编译器还允许将简单宏定义为命令行参数.例如,您可以编译代码通过gcc -DNDEBUG file1.c编译file.cNDEBUG定义为禁用assert秒.