在 c 中为相同的标识符重用#define 是否错误?
Is it erroneous to reuse #define for the same identifier in c?
K&R 书作者说
A second #define for the same identifier is erroneous unless the
second token sequence is identical to the first.
但是当我尝试时,编译器没有引发任何错误。
那么,能否请您详细说明作者想表达的意思?
如果您按照您所说的去做,它非常应该 引发诊断消息。从相关部分,C11 6.10.3 Macro replacement
:
Two replacement lists are identical if and only if the preprocessing tokens in both have the same number, ordering, spelling, and white-space separation, where all white-space separations are considered identical.
An identifier currently defined as an object-like macro shall not be redefined by another #define
preprocessing directive unless the second definition is an object-like macro definition and the two replacement lists are identical. Likewise, an identifier currently defined as a function-like macro shall not be redefined by another #define
preprocessing directive unless the second definition is a function-like macro definition that has the same number and spelling of parameters, and the two replacement lists are identical.
例如,请参阅以下抄本:
pax:/paxhome> cat prog.c
#define X 7
#define X 99
int main(void) { return 99; }
pax:/paxhome> gcc --std=c17 prog.c -o prog
prog.c:2: warning: "X" redefined
2 | #define X 99
|
prog.c:1: note: this is the location of the previous definition
1 | #define X 7
|
请记住第一段中给出的“相同”的定义,它们不必在逐个字符的基础上完全相同。根据给出的规则,以下两个可以认为是相同的:
#define X 7 + 2
#define X \
7 \
+ \
2
另请记住,gcc
将此视为警告而非错误。该标准本身仅声明必须为无效程序生成 诊断 消息,但还包含以下脚注(我强调):
Of course, an implementation is free to produce any number of diagnostics as long as a valid program is still correctly translated. It may also successfully translate an invalid program.
所以 gcc
有权简单地警告你,但无论如何都要编译程序。
如果您想将警告视为错误(我倾向于将其用于我自己的代码),您始终可以将 -Werror
标志添加到编译命令(或者可能 -Wpedantic -pedantic-errors
,具体取决于您的需要).
K&R 书作者说
A second #define for the same identifier is erroneous unless the second token sequence is identical to the first.
但是当我尝试时,编译器没有引发任何错误。 那么,能否请您详细说明作者想表达的意思?
如果您按照您所说的去做,它非常应该 引发诊断消息。从相关部分,C11 6.10.3 Macro replacement
:
Two replacement lists are identical if and only if the preprocessing tokens in both have the same number, ordering, spelling, and white-space separation, where all white-space separations are considered identical.
An identifier currently defined as an object-like macro shall not be redefined by another
#define
preprocessing directive unless the second definition is an object-like macro definition and the two replacement lists are identical. Likewise, an identifier currently defined as a function-like macro shall not be redefined by another#define
preprocessing directive unless the second definition is a function-like macro definition that has the same number and spelling of parameters, and the two replacement lists are identical.
例如,请参阅以下抄本:
pax:/paxhome> cat prog.c
#define X 7
#define X 99
int main(void) { return 99; }
pax:/paxhome> gcc --std=c17 prog.c -o prog
prog.c:2: warning: "X" redefined
2 | #define X 99
|
prog.c:1: note: this is the location of the previous definition
1 | #define X 7
|
请记住第一段中给出的“相同”的定义,它们不必在逐个字符的基础上完全相同。根据给出的规则,以下两个可以认为是相同的:
#define X 7 + 2
#define X \
7 \
+ \
2
另请记住,gcc
将此视为警告而非错误。该标准本身仅声明必须为无效程序生成 诊断 消息,但还包含以下脚注(我强调):
Of course, an implementation is free to produce any number of diagnostics as long as a valid program is still correctly translated. It may also successfully translate an invalid program.
所以 gcc
有权简单地警告你,但无论如何都要编译程序。
如果您想将警告视为错误(我倾向于将其用于我自己的代码),您始终可以将 -Werror
标志添加到编译命令(或者可能 -Wpedantic -pedantic-errors
,具体取决于您的需要).