当前位置:  开发笔记 > 编程语言 > 正文

在C宏中,应该更喜欢做{...}而(0,0)而不是{...}而(0)?

如何解决《在C宏中,应该更喜欢做{}而(0,0)而不是{}而(0)?》经验,为你挑选了3个好方法。

一位客户最近对我雇主的C代码库进行了静态分析,并向我们提供了结果.有用的补丁包括将着名do { ... } while(0)宏更改为的请求do { ... } while(0,0).我理解他们的补丁正在做什么(使用序列运算符将evaluate 返回到第二个"0"的值,因此效果是相同的)但是不清楚他们为什么喜欢第二种形式而不是第一种形式.

有没有合理的理由为什么人们应该更喜欢第二种形式的宏观,还是我们客户的静态分析过于迂腐?



1> Michael Burr..:

只是猜测他们为什么建议使用

do { ... } while(0,0)

过度

do { ... } while(0)

尽管没有行为差异,但两者之间不应存在运行时成本差异.

我的猜测是静态分析工具抱怨while循环在更简单的情况下由常量控制,而不是在0,0使用时.客户的建议可能只是因为他们没有从工具中得到一堆误报.

例如,我偶尔遇到一些情况,我希望有一个由常量控制的条件语句,但编译器会抱怨有关条件表达式求值为常量的警告.然后我必须跳过一些箍来让编译器停止抱怨(因为我不喜欢有虚假的警告).

你的客户的建议是我用来平息警告的箍之一,尽管在我的情况下它不是控制while循环,而是处理"总是失败"的断言.偶尔,我会有一个永远不会执行的代码区域(可能是交换机的默认情况).在那种情况下,我可能会有一个断言总是失败并带有一些消息:

assert( !"We should have never gotten here, dammit...");

但是,我使用的至少一个编译器会发出关于表达式始终评估为false的警告.但是,如果我将其更改为:

assert( ("We should have never gotten here, dammit...", 0));

警告消失了,每个人都很开心.我猜你的客户的静态分析工具也是如此.请注意,我通常会隐藏那些在宏后面跳跃的箍:

#define ASSERT_FAIL( x) assert( ((x), 0))

能够告诉工具供应商解决问题可能会很好,但可能存在合法的情况,他们确实想要诊断由常量布尔表达式控制的循环.更不用说即使你说服一个工具供应商进行这样的改变,这对你在明年左右的实际得到修复可能会有所帮助.


+1这可能是它,但如果是这种情况,则应使用命令行选项禁用这些警告.当你可以关闭不必要的篮球时,为什么要跳过篮球?

2> Arnaud..:

使用while(0,0)可防止Microsoft编译器生成有关常量条件的警告(警告C4127).

当启用此警告时(例如使用/ W4或/ Wall),可以根据具体情况逐个关闭它(请参阅此其他线程).

编辑:从Visual Studio 2017 15.3开始,while(0)不再发出警告(参见Constant Conditionals).你可以摆脱你的(0,0)!



3> Chris Lutz..:

好吧,我会回答一下:

有没有合理的理由为什么人们应该更喜欢宏观的第二种形式......?

不,没有合理的理由.两者总是评估为false,任何体面的编译器都可能会将第二个编译成程序集中的第一个.如果在某些情况下有任何理由使其无效,那么C已经存在很长时间了,因为这个理由可以被比我更大的大师发现.

如果你喜欢你的代码让猫头鹰盯着你,请使用while(0,0).否则,请使用C编程世界的其他部分,并告诉客户的静态分析工具.


0,0使VC++警告4127消失.这就是这种模式存在的正当理由.如果您认为0,0是一个不可接受的黑客,那么为什么你认为使用do {}而(0)本身并不是一个更糟糕的黑客?
推荐阅读
php
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有