在 C 宏中,应该更喜欢 do { … } while(0,0) 而不是 do { … } while(0) 吗?
-
13-09-2019 - |
题
一位客户最近对我雇主的 C 代码库进行了静态分析,并向我们提供了结果。有用的补丁之一是更改著名的请求 do { ... } while(0)
宏到 do { ... } while(0,0)
. 。我了解他们的补丁正在做什么(使用序列运算符 返回 评估为第二个“0”的值,因此效果是相同的)但不清楚为什么他们更喜欢第二种形式而不是第一种形式。
是否有合理的理由为什么人们应该更喜欢宏的第二种形式,或者我们客户的静态分析是否过于迂腐?
解决方案
好了,我会去一个答案:
是否有正当的理由为什么要喜欢宏的第二个形式...?
没有。没有正当的理由。双方总是为false,任何像样的编译器可能会变成第二个进入组装第一反正。如果有任何理由为它在某些情况下无效,C一直围绕远远不够长,因此要由比我更大的大师发现的。
如果你喜欢你的代码,你让猫头鹰-Y的眼睛,用while(0,0)
。否则,用什么C编程世界其他地区使用,并告诉你的客户的静态分析工具来推它。
其他提示
只是一个猜测,为什么他们会使用提示
do { ... } while(0,0)
在
do { ... } while(0)
虽然没有行为差异,应该是两者之间没有运行成本差异。
我的猜测是,静态分析工具抱怨有while
环被一个恒定在简单的情况控制,并使用0,0
时没有。客户的意见可能只是使他们不从工具得到一堆误报。
例如我偶尔遇到其中我想有由恒定控制的条件语句的情况下,但是编译器将与约一个的条件表达式的常数警告抱怨。然后,我必须通过一些跳火圈,让编译器停止抱怨(因为我不喜欢有虚假警告)。
您客户的建议是我用安静的警告箍之一,但在我的情况下,它并没有控制while
循环,这是对付一个“总是失败”的断言。偶尔,我会的代码,不应该执行区域(可能是交换机的默认情况下)。在这种情况下,我可能有一个总是失败的一些消息的断言:
assert( !"We should have never gotten here, dammit...");
但是,至少一个编译器我用的问题一个关于表达式总是评估为假警报。但是,如果将它改变为:
assert( ("We should have never gotten here, dammit...", 0));
在警告消失,大家的快乐。我猜,甚至是你的客户的静态分析工具会是这样,太。请注意,我通常隐藏箍的跳跃宏背后有点像:
#define ASSERT_FAIL( x) assert( ((x), 0))
这可能是不错的能告诉工具供应商来解决这个问题,但有可能是合法的情况下,他们实际上希望通过诊断恒定布尔表达式被控制回路。更何况事实,即使你说服工具供应商做出这样的变化,并不能帮助你在未来一年左右的时间,它可能采取真正得到修复。