如果我将零而不是变量放置,为什么输出会改变?

发布于 2025-02-06 17:16:24 字数 353 浏览 1 评论 0原文

如果您使用变量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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

十级心震 2025-02-13 17:16:24

表达式(5&lt; 4&amp;(7/x)== 0)被解析,因为

((5 < 4) & ((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_value0,这使得测试始终为else分支。

如果禁用优化,则代码生成会更改,而通过0进行除法,要么发生任何副作用(在X86处理器上提出信号)或其他一些奇怪的副作用发生(例如,表达始终使用clang -O0)。

The expression (5 < 4 & (7 / x) == 0) is parsed as

((5 < 4) & ((7 / x) == 0))

The problem is you have undefined behavior whether use x or 0 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 of 0. The right operand ((7 / x) == 0) does not have any observable side effects, besides the undefined behavior in 7 / 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 of 0. The test is therefore not taken and just the call to puts("Hello"); needs to occur.

If you replace x with its value 0, 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 of 0 so the same puts("Hello") is generated.

Undefined behavior is undefined, so assuming it just produces some value is legitimate and 0 & some_value is 0, which makes the test always take the else 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 with clang -O0).

双手揣兜 2025-02-13 17:16:24

5&lt; 4始终是07/x是一个没有可见副作用的表达式(由标准定义为文件io或访问volatile变量,特定的实现可能会提供更广泛的保证);由于不需要该子表达来计算最终结果,因此编译器被授权将其优化。

在其他情况下(该操作实际在运行时执行或在编译时间完全知道时,就像在您的问题中一样),等效表达式可能会在运行时崩溃或给出编译时间警告/错误好吧:零除法是未定义的行为,因此允许编译器做任何自己喜欢的事情(包括假设在优化时不会发生)。

5 < 4 is always 0, and 7 / x is an expression without visibile side-effects (defined by the standard as file IO or access to volatile 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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文