为啥 Microsoft 的 C/C++ 编译器允许使用逗号分隔表达式的 if 语句? [复制]
Posted
技术标签:
【中文标题】为啥 Microsoft 的 C/C++ 编译器允许使用逗号分隔表达式的 if 语句? [复制]【英文标题】:Why is a if-statement with comma-separated expressions allowed by Microsoft's C/C++ compiler? [duplicate]为什么 Microsoft 的 C/C++ 编译器允许使用逗号分隔表达式的 if 语句? [复制] 【发布时间】:2016-01-13 12:04:10 【问题描述】:我最近在将 c++ 项目从 Windows 移植到 Linux 时偶然发现了一些语法上看起来很奇怪的代码。
if ( isObjectNear( objectPos, objectLength ) + .025, 0.125 ) ... "
在这个 if 语句中,括号放错了位置,导致语句由两个用逗号分隔的表达式组成。布尔 "isObjectNear(..)" 方法具有默认参数,允许使用 Microsoft 的编译器进行调用,尽管存在明显错误。
在使用 GCC 的 Linux 上构建时,发现问题并给出错误消息:
错误:计算的值未使用 [-Werror=unused-value]
在我的例子中,代码比与问题相关更有趣,以下代码通过 cmets 中的返回值更清楚地服务于问题的目的:
if ( true, 0.5 ) ... // returns true since 0.5 > 0 ( 0 == false)
if ( true, 0.0 ) ... // returns false
if ( 1.0, false ) ... // returns false
if ( true, false, false, ..., true ) ... // returns true
回到问题“为什么微软的 C/C++ 编译器允许使用逗号分隔表达式的 if 语句?”
【问题讨论】:
因为comma operator. GCC 允许。只是您设置了-Werror
,所以警告被报告为错误。
“逗号运算符”已经从我身边经过,就像你 @PaulR 有效地评论解释了这一切。使用 gcc 时设置了 -Werror 标志也是如此。感谢您分享您的知识!
@JonatanHägglund:是的,这是一个常见的错误来源——我不止一次看到人们写像if (a > 0, b > 0)
这样的东西,它应该是if (a > 0 && b > 0)
,因为它编译没有错误它可能导致在某些情况下是讨厌的潜在错误。
@AdrianMcCarthy 是的,我的错!就像我在 cmets 中提到的那样,直到现在我才知道逗号运算符。我将删除该行,因为它是一个错误的陈述。感谢您提及!
【参考方案1】:
允许,因为它在语法上是正确的,并且符合标准的编译器必须接受它。
GNU 编译器猜测丢弃左手表达式的结果不是故意的,并有助于向您发出警告。您已经告诉编译器将警告视为错误。如果您没有这样做,那么 gcc 也会允许。
标准不要求编译器在不使用表达式的结果时给出诊断,微软可能选择不这样做。即使在 gcc 中,Wall
也没有启用 Wunused-value
,这表明它被认为是一个可能有很多误报的选项。不过,我不认为这个案例是误报。在我看来,这是一个明显的程序员错误。
编辑。正如 Richard Crittenden 所评论的,显然 msvc 也会发出警告。
【讨论】:
“尽管存在明显错误,但允许使用 Microsoft 的编译器进行调用” - 这是避免使用类似瘟疫的 Microsoft 编译器的众多原因之一。 谢谢!我完全错过了“逗号运算符”,可以看到它在哪里有用,但也可以看到(在这种情况下)接受错别字的风险。确实,gcc 被设置为将警告视为错误。很高兴学到新东西! @RichardHodges 它被 MS 编译器在警告级别 4 捕获。 很高兴知道它已添加到答案中!我希望这个问题不会让人认为 MS 编译器无法检测到并发出警告。以上是关于为啥 Microsoft 的 C/C++ 编译器允许使用逗号分隔表达式的 if 语句? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
装Kingbase ES V7时为啥依赖检测时,总是提示我说Microsoft Visual C++ 2008未通过检测???
为啥此 C++ 代码仅在 Microsoft 编译器上具有模棱两可的方法调用?