【问题标题】:How to get rid of the need to define a preprocessor macro for conditional compilation? [closed]如何摆脱为条件编译定义预处理器宏的需要? [关闭]
【发布时间】:2018-10-19 13:55:43
【问题描述】:

我根据#define 编译了一些 C++ 代码。今天我错误地忘记#include定义的文件,这导致我的程序被错误的代码编译。

我有哪些选择可以消除这个潜在的错误?

【问题讨论】:

  • 重构你的代码不需要它?用另一种方式回答如此广泛的问题有点困难。
  • 这真的取决于他们在做什么。在没有看到代码的情况下,我们无法为您提供太多具体的建议。
  • “我今天遇到的一个问题是我忘记添加文件”使用C++时不能忘记添加文件,您可以轻松获得UB。
  • OP,你的问题不清楚,但我想我还是明白了。我已经编辑过了。如果您认为它没有更好,您可以将您的问题回滚到原来的样子。

标签: c++


【解决方案1】:

大多数编译器允许您在编译命令行中定义预处理器宏。例如,g++ 和 clang++ 有-DMACRO=VALUE

trunit.cpp:

#include <iostream>

int main() {
    #ifdef ALT_FOO
        std::cout << "BAR\n";
    #else
        std::cout << "FOO\n";
    #endif // ALT_FOO
}

在当前情况下,此代码的行为取决于是否包含定义宏 ALT_FOO 的头文件。您可以从构建过程本身进行控制:

$ # build the FOO variant:
$ g++ -Wall -Wextra -Werror -pedantic -O2 trunit.cpp -o foo
$ ./foo
FOO

$ # build the BARvariant:
$ g++ -Wall -Wextra -Werror -pedantic -O2 -DALT_FOO trunit.cpp -o foo
$ ./foo
BAR

【讨论】:

    【解决方案2】:

    具有#define FOO#define NFOO 的宏标头。

    然后您将测试要定义的 FOONFOO 之一

    #if defined(FOO) && defined(NFOO)
    #error both FOO and NFOO defined
    #elif defined (FOO) 
        // foo case
    #elif defined (NFOO) 
        // not foo case
    #else
    #error neither FOO nor NFOO defined
    #end
    

    【讨论】:

    • 我更喜欢这个解决方案,因为它不会污染定义编译器命令。但是在此基础上,我认为使用值可以变得更好;未定义的 var 为 0,因此 1 可能是“已定义”,而 2 可能是“未定义”并避免双重声明的问题:#lif defined (FOO == 1) // foo case #elif defined (FOO == 2 ) // not foo case #else #error FOO not defined #end
    • @mauro 如果未定义FOO,则它既不是01 也不是2。你必须#if defined(FOO) #if FOO == 1 ... #elif FOO == 2 ... #else #error unknown FOO #end #else #error missing FOO #end,这也相当冗长
    • 标准明确说“剩余标识符”设置为0,见stackoverflow.com/questions/5085392/…
    猜你喜欢
    • 2011-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-29
    • 1970-01-01
    • 2011-02-12
    相关资源
    最近更新 更多