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

标签 c macros language-lawyer c-preprocessor preprocessor-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.

我的问题:

  • 我可以通过忽略此特定警告来使用另一个 #define 指令重新定义宏吗?
  • 这是否涉及未定义的行为或对程序造成潜在损害?

非常感谢。

最佳答案

重新定义宏(当重新定义不相同时)违反约束。该约束在 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

关于我可以使用另一个 #define 指令重新定义宏吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60619149/

相关文章:

c++ - pcap_stats 是否在 Ubuntu 14.04 LTS 上实现?

c++ - 构建一组对象并将它们放入一个元组中

c++ - 模板忽略 [[nodiscard]] 属性

c++ - const 指向成员的指针是否默认指向一个 int?

c - 没有语句的无限 While 循环

克隆命令 `script` 和 PTY 后台作业问题 : terminal messed up

c - 下面的 va_arg 宏是如何工作的?

macros - 在构建宏中访问 Context.getLocalClass() 的 Class<T>

c++ - [[maybe_unused]] 在枚举器上

c - 使用C语言中的递归函数搜索数组中的元素