简体   繁体   English

编译器开关还是预处理器开关?

[英]Compiler switch or preprocessor switch?

Switching code using the preprocessor is pretty common: 使用预处理器切换代码非常普遍:

#define MY_SWITCH (1)
#if MY_SWITCH
   cout << "on" << Test(1);
#else
   cout << "off" << Test(2);
#endif

However if the code outside this snippet changes (eg if the Test() function is renamed) it could happen that the disabled line would remain outdated since it is not compiled. 但是,如果此代码段外部的代码发生更改(例如,如果Test()函数已重命名),则可能发生禁用的行将保持过期的情况,因为未编译该行。

I would like to do this using a different kind of switch to let the code being compiled on every build so I can find outdated lines immediately. 我想使用另一种类型的开关来执行此操作,以使代码可以在每次构建中进行编译,这样我就可以立即找到过时的行。 Eg like this: 例如:

static const bool mySwitch = true;
if (mySwitch)
{
   cout << "on" << Test(1);
}
else
{
   cout << "off" << Test(2);
}

However I need to prevent this method to consumes additional ressources. 但是,我需要防止此方法消耗其他资源。 Is there any guaranty (or a reliable assumption) that modern C++ compilers will remove the inactive branch (eg using optimization)? 现代C ++编译器是否有任何保证(或可靠的假设)会删除不活动的分支(例如,使用优化)?

I had this exact problem just a few weeks ago — disabling a problematic diagnostic feature in my codebase revealed that the alternative code had some newish bugs in it that prevented compilation. 就在几周前,我遇到了这个确切的问题-在我的代码库中禁用了有问题的诊断功能后,发现替代代码中包含一些新的错误,阻止了编译。 However, I wouldn't go down the route you propose. 但是,我不会按照您的建议去做。

You're sacrificing the benefit of using macros in the first place and not necessarily gaining anything. 首先,您要牺牲使用宏的好处,而不一定获得任何好处。 I expect my compiler to optimise the dead branch away but you can't rely on it and I feel that the macro approach makes it a lot more obvious that there are two distinct "configurations" of your program and only one can ever be used from within a particular build. 我希望我的编译器可以优化死分支, 但是您不能依靠它, 而且我认为宏方法使程序有两个截然不同的“配置”变得更加明显,并且在其中只有一个可以使用在特定版本中。

I would let your continuous integration system (or whatever is driving automated build tests) cycle through the various combinations of build configuration (provide macros using -D on the commandline, possibly from within your Makefile or other build script, rather than hardcoding them in the source) and test them all . 我会让您的持续集成系统(或正在推动自动构建测试的任何事物)在构建配置的各种组合之间循环(可能在您的Makefile或其他构建脚本中使用命令行上的-D提供宏,而不是在来源), 并全部测试

You don't have guarantee about compiler optimization. 您不能保证编译器的优化。 (If you want proven optimizations for C, look into compcert ). (如果您需要经过验证的C优化,请查看compcert )。

However, most compilers would optimize in that case, and some might even warn about dead code. 但是,大多数编译器会在这种情况下进行优化,甚至有一些甚至会警告死代码。 Try with recent GCC or Clang/LLVM with optimizations enabled (eg g++ -Wall -Wextra -O2 ). 尝试使用启用了优化功能的最新GCCClang / LLVM (例如g++ -Wall -Wextra -O2 )。

Also, I believe that most compilers won't consume resources at execution time of the generated optimized code, but they will consume resources at compilation time. 另外,我相信大多数编译器在生成的优化代码执行时不会消耗资源,但是它们会在编译时消耗资源。

Perhaps using constexpr might help some compilers to optimize better. 也许使用constexpr可能会帮助某些编译器进行更好的优化。

Also, look at the produced assembly code (eg with g++ -O2 -fverbose-asm -S ) or at the intermediate dumps of the compiler (eg g++ -O2 -fdump-tree-all which gives hundreds of dump files). 另外,查看生成的汇编代码(例如,使用g++ -O2 -fverbose-asm -S )或编译器的中间转储(例如, g++ -O2 -fdump-tree-all提供数百个转储文件)。 If using GCC, you might customize it with MELT to eg add additional compile-time checks. 如果使用GCC,则可以使用MELT对其进行自定义,例如,添加其他编译时检查。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM