编译器:假设条件总是真/假
Compiler: What if condition is always true / false
我想到了条件语句和编译器。我正在为Arduino编程一个应用程序,所以我需要这个应用程序尽可能快。
在我的代码中,我有这个:
#define DEBUG false
...
if (DEBUG)
{
String pinName;
pinName = "Pin ";
pinName += pin;
pinName += " initialized";
Serial.println(pinName);
}
我想知道编译器是否不包括二进制文件中的代码(if块中的代码(。条件总是错误的,所以程序永远不会去那里。
从另一边。如果DEBUG是真的呢?Arduino测试条件还是编译器在二进制文件中只包含if的主体?
我发现了这个网站https://gcc.gnu.org/onlinedocs/gcc-3.0.2/cpp_4.html关于#if指令,所以我可以重写代码,使其具有这些指令,而不是"正常"if。但我想知道我是否应该重写它,或者它是否会浪费时间。
任何半成品的优化编译器都会删除if语句中的整个代码,前提是它可以在编译时告知条件总是计算为false。类似地,如果条件总是真的,任何半成品编译器都会跳过检查本身。
事实上,这完全等同于"编译器开关",例如:
#define DEBUG
#ifdef DEBUG
...
#endif
#ifdef
的"编译器切换"语法更可取,因为它使其他C程序员的意图更清晰。但这只是编码风格的问题——它将产生与原始代码相同的二进制代码。
您编写的代码永远不应该被执行,但是,它可以在可执行文件中使用。
我想说的是,当您禁用优化(例如将-O0
添加到Clang和GCC(时,编译器将需要保留此代码。在所有其他情况下,我希望编译器能删除代码,因为这是一个非常简单的优化,具有显著的代码大小效应。例如,GCC在-O
及更高级别消除了这种情况。(参见手册(
不过,还有另外两种编写代码的方法,它们将强制不包含此代码:
- 预处理器条件
- constexpr if
通过使用预处理器条件,您将能够在代码到达实际编译器之前删除代码。虽然它可以与C和C++标准的所有编译器和版本一起使用,但它可能会对缩进造成一些干扰。
#ifdef DEBUG
{ // Optional: Adding extra scope to prevent usage of local variables after the endif
// Code to eliminate
}
#endif
然而,如果你使用的是C++17,你也可以使用constexpr if。这在你的代码中会减少干扰,尽管if语句中的代码必须是语法正确的,但它不必编译(因此在语义上不正确(。
这可以写成:
if constexpr (DEBUG)
{
// Code to eliminate
}
我不喜欢回答我自己的问题,因为如果没有你们的帮助,我不会解决的,伙计们。
无论如何,第一个选项是使用:
#if DEBUG == true
#endif
或
#ifdef DEBUG
#endif
编译器没有在#if/#ifdef中获得代码(预处理器将其删除(,因此,如果这部分代码中存在问题,如果DEBUG设置为false或根本没有定义,则没有人会知道这一点(谢谢@Klaus(。
第二种选择:
#define DEBUG false
...
if (DEBUG)
{
...
}
如果条件为false,则任何较新的编译器都应删除"if"块;如果条件为true,则应删除"if"语句并保留正文。
所以我想说,这取决于程序员,哪种方法更适合应用程序的需求。
如果您需要确保代码不会包含在二进制文件中,那么第一种方法会更好。
如果您希望编译器在每次编译程序时检查整个代码,那么第二种方法会更好。
如果你喜欢这个答案,投赞成票,我会接受的——如果没有人提供更好的答案。
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 在没有太多条件句的情况下,我如何避免被零除
- 基于多个条件处理地图中的所有元素
- 条件constexpr函数
- 无论条件是否为true,if总是在c++中执行
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 基于模板值的条件变量
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 将按位if条件转换为普通if条件
- 条件断点在不应该触发时触发
- 为什么简单的算术减法在"if"条件下不起作用?
- 如何在for循环中包含两个索引值的测试条件
- 如果条件为TRUE(最佳方式?),则在do while循环中后置增量
- 我提出什么条件才能再加5%的折扣
- 循环中的条件:为什么每次都调用strlen(),而vector.size()只调用一次
- 即使没有满足他们的条件,我也无法通过一些 do-while 循环
- 如何编写一个使用n倍三元条件语句的C++布尔函数
- 没有超时的C++条件变量
- 正在LLVM中检测整数比较条件
- 编译器:假设条件总是真/假