【问题标题】:What happens when you redefine a macro?重新定义宏时会发生什么?
【发布时间】:2016-10-24 10:13:01
【问题描述】:
#define MY_MACRO 3 --> in A.h
#define MY_MACRO 45 --> B.h

//In C.cpp

#include "A.h"
#include "B.h"

..
..
..
int my_value = MY_MACRO;

my_value 是 3 还是 45?

【问题讨论】:

  • 你尝试了什么?发生了什么?
  • @AbdusSalamKhazi 如果你有一个巨大的项目,你不应该有 2 个不同值的宏。删除哪一个取决于具体情况。您应该仔细查看并删除不正确的。
  • 只有你才能知道,通过研究和理解代码,并确定它应该如何表现。如果您出于某种原因(为什么?)无法做到这一点,请向团队中的同事寻求帮助。
  • @Asu - 很棒的建议!除非你错了。 C++ 不是说“试试看”的好语言,因为它有Undefined Behaviour。 (See paragraph 2)。但是,behaviour with gcc is to use the latter definition,这不是到处都能保证的!

标签: c++ c macros


【解决方案1】:

来自标准(草案)[cpp.replace] §2

当前定义为类对象宏的标识符(见下文)可以由另一个#define 重新定义 预处理指令,前提是第二个定义是类似对象的宏定义,并且两个 替换列表是相同的,否则程序格式错误。 [...]


重新定义宏会发生什么?

当新定义不同时,您的程序是不正确的。编译器需要向您显示诊断消息(警告或错误)。标准未定义格式错误程序的行为。编译器可以拒绝编译程序。

my_value 是 3 还是 45?

无论您的预处理器/编译器选择什么。或者编译器可以拒绝编译它。


从技术上讲,如果您首先取消定义宏,程序会变得结构良好。那么定义的值显然是新定义的。但是,我不建议这样做,因为您可以根据在多个翻译单元中包含标题的顺序轻松打破其他规则。

最有可能的是,这两个宏应该是单独的实体,并且有不同的文件期望来自一个标题而不是另一个标题的定义。正确的解决方案是通过重命名为每个文件赋予一个 唯一 名称,并更改依赖文件以使用新名称。弄清楚哪些文件使用哪个定义可能是一个挑战。当您使用它时,您可能希望将宏替换为 constexpr 变量。

【讨论】:

  • constexpr有什么用?
  • @AbdusSalamKhazi 它允许您在需要常量表达式的上下文中使用变量。
  • 那么尝试在没有#undef 的情况下重新定义宏具有实现定义的行为?
  • @Sapphire_Brick 尝试这样做会使程序在定义更改时格式错误。实现不需要记录你的行为。
【解决方案2】:

我想

重新定义宏会发生什么?

它给出了宏的重新定义警告。

还是

如果您避免警告并尝试运行您的程序

那么我们就知道在cpp中所有的语句都是从上到下顺序执行的,所以不管宏的最后一个定义是什么打印出来的。

my_value 是 3 还是 45?

您的代码中的 45 将被视为宏定义。

【讨论】:

    猜你喜欢
    • 2018-07-20
    • 2015-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多