Luc*_*ore 61 c c++ language-lawyer
我对以下代码中的一些同事存在分歧:
int foo ( int a, int b )
{
return b > 0 ? a / b : a;
}
Run Code Online (Sandbox Code Playgroud)
此代码是否显示未定义的行为?
编辑:分歧开始于过度热切的优化编译器中的错误,其中b > 0检查已经过优化.
krz*_*zaq 109
没有.
来自N4140的行情:
§5.16[expr.cond]/1
条件表达式从右到左分组.第一个表达式在上下文中转换为bool.它被评估,如果是,则条件表达式的结果是第二个表达式的值,否则是第三个表达式的值.仅 评估第二和第三表达式中的一个.
进一步:
§5[expr]/4
如果在评估表达式期间,结果未在数学上定义或未在其类型的可表示值范围内,则行为未定义.
这显然不会发生在这里.同一段在一个说明中明确提到除零,虽然它是非规范性的,但它更清楚地表明它与这种情况有关:
[注意:大多数现有的C++实现忽略整数溢出.除零处理,使用零除数形成余数,所有浮点异常因机器而异,通常可通过库函数调整. - 尾注]
还有一些间接证据强调了上述观点:条件运算符用于有条件地使行为未定义.
§8.5[dcl.init] /12.3
Run Code Online (Sandbox Code Playgroud)int f(bool b) { unsigned char c; unsigned char d = c; // OK, d has an indeterminate value int e = d; // undefined behavior return b ? d : 0; // undefined behavior if b is true }
在上面的示例中,使用d初始化int(或其他任何内容unsigned char)是未定义的.然而,明确指出UB仅在评估UB分支时发生.
走出语言 - 律师观点:如果这可能是UB,那么任何分裂都可以被视为UB,因为除数可能是0.这不是规则的精神.
gla*_*ver 15
在示例代码中无法用零除.当处理器执行时a / b,它已经检查过b > 0,因此b非零.
应该注意的是,如果a == INT_MIN和b == -1,那么a/b也是未定义的行为.但无论如何都要防止这种情况,因为false在这种情况下条件会进行评估.
虽然我不是很确定你的意思return b != 0 ? a / b : a;而不是return b > 0 ? a / b : a;如果b小于零,除非它是上述条件,否则除法仍然有效.
此代码是否显示未定义的行为?
不,它没有.表达方式
return b > 0 ? a / b : a;
Run Code Online (Sandbox Code Playgroud)
相当于
if(b > 0)
return a/b; // this will be executed only when b is greater than 0
else
return a;
Run Code Online (Sandbox Code Playgroud)
只有当b大于时才执行除法0.
| 归档时间: |
|
| 查看次数: |
3815 次 |
| 最近记录: |