我可以用另一个#define 指令重新定义宏吗?

Can I redefine a macro with another #define directive?

我想用另一个值重新定义宏常量的值。现在我知道使用 #undef 的技术,然后重新 #define 宏本身,例如:

#define LEN_OSG 59
....
#undef LEN_OSG
#define LEN_OSG 70

我试图缩写它并发现 可能 仅通过另一个 #define 指令重新定义宏常量:

#define LEN_OSG 59
....
#define LEN_OSG 70

Example program:

#include <stdio.h>

#define LEN_OSG 59

int main()
{

    printf("LEN_OSG is %d.\n",LEN_OSG);

    #define LEN_OSG 70

    printf("LEN_OSG is %d.",LEN_OSG);
}

当然,gcc 和 clang 都给我警告:

warning: "LEN_OSG" redefined. (gcc)

warning: 'LEN_OSG' macro redefined [-Wmacro-redefined] (clang)

但他们确实编译了它(当然没有 -Werror 选项)并给出了正确的结果:

Execution build compiler returned: 0
Program returned: 0
LEN_OSG is 59.
LEN_OSG is 70.

我的问题:

非常感谢。

在重新定义宏之前,您真的应该习惯使用 #undef!大多数编译器会生成警告;然而,根据 C99 Standard (and also the C18 Standard - 两个段落是相同的):

6.10.3 Macro replacement
...
2 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.

您示例中 LEN_OSG(类对象)宏的 'replacement lists' 是 59,然后是 70 - 不是 相同。

重新定义宏(当重新定义不同时)是违反约束。该约束在 C standard:

的第 6.10.3p2 节中有详细说明

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.

第 4p2 节说明了以下有关约束违规的内容:

If a ‘‘shall’’ or ‘‘shall not’’ requirement that appears outside of a constraint or runtime-constraint is violated, the behavior is undefined. Undefined behavior is otherwise indicated in this International Standard by the words ‘‘undefined behavior’’ or by the omission of any explicit definition of behavior. There is no difference in emphasis among these three; they all describe ‘‘behavior that is undefined’’.

因此重新定义宏会调用 undefined behavior。如果您想重新定义宏,您必须使用#undef