如果我将零而不是变量放置,为什么输出会改变?
如果您使用变量x
而不是0
输出将为Hello
。如果您使用0
编译器将显示有关除以零的警告。代码如下:
#include <stdio.h>
int main(int argc, char const *argv[])
{
int x = 0;
if (5 < 4 & (7 / x) == 0)
puts("dividing by zero");
else
{
puts("Hello");
}
return 0;
}
If you use the variable x
instead of 0
the output will be Hello
. If you use 0
the compiler will display a warning about dividing by zero. The code is below:
#include <stdio.h>
int main(int argc, char const *argv[])
{
int x = 0;
if (5 < 4 & (7 / x) == 0)
puts("dividing by zero");
else
{
puts("Hello");
}
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
表达式
(5&lt; 4&amp;(7/x)== 0)
被解析,因为问题是您有 undectined行为是否使用
x 或
0
,因此任何事情都可能发生,并且C标准无法定义编译器应该做什么。查看编译器评估
(5&amp; 4)
作为常数表达式,值为0
。正确的操作数(((7 / x)== 0)< / code>没有任何可观察的副作用,除了
7 / x < / x < / code>中的未定义行为,从定义上讲是 未定义。如果启用了优化,则编译器似乎忽略了潜在的未定义行为,并在编译时间确定整个表达式的值为
0
。因此,未进行测试,只需调用puts(“ hello”);
需要进行。如果您替换
x
其值0
,则编译器将整个表达式评估为恒定表达式,它不能忽略((7/0)) == 0)
具有未定义的行为,因此它会生成诊断,但似乎仍然忽略了未定义的行为,整个表达式仍然具有0
的值,因此相同的puts( “你好”)
是生成的。未定义的行为是未定义的,因此假设它仅产生某些价值是合法的,
0&amp; Some_value
是0
,这使得测试始终为else
分支。如果禁用优化,则代码生成会更改,而通过
0
进行除法,要么发生任何副作用(在X86处理器上提出信号)或其他一些奇怪的副作用发生(例如,表达始终使用clang -O0
)。The expression
(5 < 4 & (7 / x) == 0)
is parsed asThe problem is you have undefined behavior whether use
x
or0
so anything can happen and the C Standard does not define what the compiler should do. Looking at the compiler output on godbolt.org, the behavior of the program differs for different compiles and different compiler options.The compiler evaluates
(5 & 4)
as a constant expression with a value of0
. The right operand((7 / x) == 0)
does not have any observable side effects, besides the undefined behavior in7 / x
which by definition is undefined. If optimisations are enabled, the compiler seems to ignore the potential undefined behavior and determines at compile time that the whole expression has a value of0
. The test is therefore not taken and just the call toputs("Hello");
needs to occur.If you replace
x
with its value0
, as the compiler evaluates the whole expression as a constant expression, it cannot ignore the fact that((7 / 0) == 0)
has undefined behavior so it generates a diagnostic, but seems to still ignore the undefined behavior, the whole expression still has a value of0
so the sameputs("Hello")
is generated.Undefined behavior is undefined, so assuming it just produces some value is legitimate and
0 & some_value
is0
, which makes the test always take theelse
branch.If you disable the optimisations, the code generation changes and the division by
0
either occurs with whatever side effects (a signal is raised on x86 processors) or some other weird side effect occurs (such as the expression becoming always true withclang -O0
).5&lt; 4
始终是0
,7/x
是一个没有可见副作用的表达式(由标准定义为文件io或访问volatile
变量,特定的实现可能会提供更广泛的保证);由于不需要该子表达来计算最终结果,因此编译器被授权将其优化。在其他情况下(该操作实际在运行时执行或在编译时间完全知道时,就像在您的问题中一样),等效表达式可能会在运行时崩溃或给出编译时间警告/错误好吧:零除法是未定义的行为,因此允许编译器做任何自己喜欢的事情(包括假设在优化时不会发生)。
5 < 4
is always0
, and7 / x
is an expression without visibile side-effects (defined by the standard as file IO or access tovolatile
variables, specific implementations may give wider guarantees); as that sub-expression is not required to compute the final result, the compiler is authorized to optimize it out.The fact that in other contexts (when that operation is actually performed at runtime, or when it's fully known at compile time, as in your question) an equivalent expression may crash the program at runtime or give a compile time warning/error is allowed as well: division by zero is undefined behavior, so the compiler is allowed to do whatever it pleases (including assuming it won't happen when optimizing).