Google C ++样式指南(http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Preprocessor_Macros)说:
“而不是使用宏来有条件地编译代码......好吧,根本不要这样做”
为什么有像
这样的功能这么糟糕void foo()
{
// some code
#ifdef SOME_FUNCTIONALITY
// code
#endif
// more code
}
答案 0 :(得分:3)
正如他们在您链接到的文档中所说:
宏意味着您看到的代码与编译器看到的代码不同。这可能会引入意外行为,尤其是因为宏具有全局范围。
如果您只有一个条件编译,那也不算太糟糕,但如果您开始使用嵌套的编译,则会变得非常复杂:
#if PS3
...
#if COOL_FEATURE
...
#endif
...
#elif XBOX
...
#if COOL_FEATURE
...
#endif
...
#elif PC
...
#if COOL_FEATURE
...
#endif
...
#end
答案 1 :(得分:1)
我相信反对它的一些论点:
#ifdef
削减了C ++表达式/ statement / function / class语法。也就是说,与goto
一样,它太灵活,您无法信任自己使用它。
假设// code
中的代码未定义SOME_FUNCTIONALITY
时编译。然后只需将if
与static const bool
一起使用,并相信您的编译器可以消除死代码。
假设未定义// code
时SOME_FUNCTIONALITY
中的代码未编译。然后你要创建一个狗的早餐,其中包含有效代码和无效代码,以及相关代码和无关代码,可以通过更彻底地分离这两个案例来改进。
预处理器是一个可怕的错误:Java比C或C ++更好,但是如果我们想在金属附近捣乱,我们会坚持使用它们。尝试假装#
字符不存在。
明确的条件是一个可怕的错误:多态性宝贝!
Google的样式指南专门提到测试:如果您使用#ifdef
,那么您需要两个单独的可执行文件来测试代码的两个分支。这很麻烦,您应该更喜欢单个可执行文件,可以针对所有支持的配置进行测试。当然,同样的异议在逻辑上适用于static const bool
。通常,当您避免静态依赖时,测试会更容易。喜欢注入它们,即使“依赖”只是一个布尔值。
我并没有单独出售任何论据 - 我个人认为,在特定情况下,杂乱的代码有时仍然是特定工作的最佳代码。但谷歌C ++风格指南不是告诉你使用你的最佳判断。它的目的是设置统一的编码风格,并消除作者不喜欢或不信任的一些语言特征。