我对#define
陈述有些困惑。在库中,它们似乎是一种跨不同文件的通信方式,有很多#ifdef
s 和#ifndef
s。
话虽如此,我现在有两个文件file1.c
并file2.c
一起编译,#define TEST 10
里面有file2.c
. 然而,当我在编译器TEST
内部使用时file2.c
,会出现以下错误消息:
'TEST' undeclared (first use in this function)
#define
指令是全球性的吗?
我对#define
陈述有些困惑。在库中,它们似乎是一种跨不同文件的通信方式,有很多#ifdef
s 和#ifndef
s。
话虽如此,我现在有两个文件file1.c
并file2.c
一起编译,#define TEST 10
里面有file2.c
. 然而,当我在编译器TEST
内部使用时file2.c
,会出现以下错误消息:
'TEST' undeclared (first use in this function)
#define
指令是全球性的吗?
#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
to compile file.c
with NDEBUG
defined to disable编译您的代码assert
。
以防有人稍后阅读此内容,并添加一些实用信息:
归根结底,您将不得不以一种或另一种方式将该全局 hfile 或全局指令提供给编译器。
你应该制作一个 file1.h 并将你的定义放在那里。然后在file2.c
#include "file1.h"
像馅饼一样容易:)