在 C 宏中,是否应该更喜欢 do { ... } while(0,0) 而不是 do { ... } while(0) ?
一位客户最近对我雇主的 C 代码库进行了静态分析,并向我们提供了结果。有用的补丁之一是更改著名的 do { ... } while(0)
宏到 do { ... } while(0,0)
。我了解他们的补丁正在做什么(使用序列运算符 return 评估第二个“0”的值,因此效果是相同的),但不清楚为什么他们喜欢第二个形式覆盖第一个形式。
是否有合理的理由为什么人们应该更喜欢宏的第二种形式,或者我们客户的静态分析是否过于迂腐?
A customer recently performed static analysis of my employer's C codebase and gave us the results. Among useful patches was the request to change the famous do { ... } while(0)
macro to do { ... } while(0,0)
. I understand what their patch is doing (using the sequence operator to return evaluate to the value of the second "0", so the effect is the same) but it's not clear why they'd favor the second form over the first form.
Is there a legitimate reason why one should prefer the second form of the macro, or is our customer's static analysis being overly pedantic?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
只是猜测为什么他们可能建议使用
over
即使两者之间没有行为差异并且应该没有运行时成本差异。
我的猜测是,静态分析工具会抱怨
while
循环在更简单的情况下由常量控制,而在使用0,0
时则不会。客户的建议可能只是为了让他们不会从该工具中得到一堆误报。例如,我偶尔会遇到这样的情况:我想要一个由常量控制的条件语句,但编译器会发出有关条件表达式计算为常量的警告。然后我必须跳过一些麻烦才能让编译器停止抱怨(因为我不喜欢出现虚假警告)。
您客户的建议是我用来消除该警告的方法之一,尽管在我的例子中,它不是控制
while
循环,而是处理“总是失败”的断言。有时,我会有一个永远不应该执行的代码区域(可能是开关的默认情况)。在这种情况下,我的断言可能总是失败并显示一些消息:但是,我使用的至少一个编译器会发出有关表达式始终评估为 false 的警告。但是,如果我将其更改为:
警告就会消失,每个人都会很高兴。我猜即使您客户的静态分析工具也会如此。请注意,我通常将跳圈隐藏在宏后面,例如:
能够告诉工具供应商解决问题可能会很好,但可能存在合法的情况,他们实际上确实想要诊断由一个常量布尔表达式。更不用说即使您说服工具供应商做出这样的更改,这对您在明年左右的时间也没有帮助,因此可能需要实际修复。
Just a guess as to why they might suggest using
over
Even though there's no behavior difference and should be no runtime cost difference between the two.
My guess is that the static analysis tool complains about the
while
loop being controlled by a constant in the simpler case and doesn't when0,0
is used. The customer's suggestion is probably just so they don't get a bunch of false positives from the tool.For example I occasionally come across situations where I want to have a conditional statement controlled by a constant, but the compiler will complain with a warning about a conditional expression evaluating to a constant. Then I have to jump through some hoops to get the compiler to stop complaining (since I don't like to have spurious warnings).
Your customer's suggestion is one of the hoops I've used to quiet that warning, though in my case it wasn't controlling a
while
loop, it was to deal with an "always fails" assertion. Occasionally, I'll have an area of code that should never execute (maybe the default case of a switch). In that situation I might have an assertion that always fails with some message:But, at least one compiler I use issues a warning about the expression always evaluating to false. However, if I change it to:
The warning goes away, and everybody's happy. I'm guessing that even your customer's static analysis tool would be, too. Note that I generally hide that bit of hoop jumping behind a macro like:
It might be nice to be able to tell the tool vendor to fix the problem, but there might be legitimate cases where they actually do want to diagnose a loop being controlled by a constant boolean expression. Not to mention the fact that even if you convince a tool vendor to make such a change, that doesn't help you for the next year or so that it might take to actually get a fix.
使用
while(0,0)
可以防止 Microsoft 编译器生成有关常量条件的警告(警告 C4127)。当启用此警告时(例如使用 /W4 或 /Wall),可以根据具体情况使用这个不错的小技巧将其关闭(请参阅另一个线程)。
编辑:自 Visual Studio 2017 15.3 起,
while(0)
不再发出警告(参见 常量条件)。您可以摆脱您的(0,0)
!Using
while(0,0)
prevents Microsoft compiler from generating a warning about a condition which is a constant (Warning C4127).When this warning is enabled (e.g. with /W4 or /Wall), it can be shut down on a case by case basis with this nice little trick (see this other thread).
EDIT: Since Visual Studio 2017 15.3,
while(0)
does not emit warnings anymore (cf. Constant Conditionals). You can get rid of your(0,0)
!好吧,我去寻求答案:
不,没有正当理由。两者的计算结果总是为 false,并且任何像样的编译器都可能将第二个编译器转换为程序集中的第一个编译器。如果有任何原因导致它在某些情况下无效,C 已经存在了足够长的时间,以至于比我更伟大的大师都发现了这个原因。
如果你喜欢你的代码让你的代码用猫头鹰的眼睛看着你,请使用
while (0,0)。否则,请使用 C 编程世界的其他部分所使用的内容,并告诉客户的静态分析工具来推送它。
Well, I'll go for an answer:
No. There is no legitimate reason. Both always evaluate to false, and any decent compiler will probably turn the second one into the first in the assembly anyway. If there was any reason for it to be invalid in some cases, C's been around far long enough for that reason to be discovered by greater gurus than I.
If you like your code making owl-y eyes at you, use
while(0,0)
. Otherwise, use what the rest of the C programming world uses and tell your customer's static analysis tool to shove it.