为什么这段代码被解析为真?

Xor*_*rty 13 c

int main() {
    int a = 1;
    int b = 0;

    if (a = b || ++a == 2)
        printf("T: a=%i, b=%i", a, b);
    else
        printf("F: a=%i, b=%i", a, b);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我们来看看这个简单的代码片段.结果是:T:a = 1,b = 0

为什么?(注意a=b使用赋值操作数,而不是比较)

我在这里理解的是,被分配给a,然后a增加到1. 1不等于2.因此结果应该是a = 1,b = 0.但为什么这个条件评估为真?既不是(a=b)也不(++a == 2)是真的......我错过了什么?

这是其他短程序,按预期打印F:

int main() {
    int a = 1;
    int b = 0;

    if (a = b) printf("T"); else printf("F");

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

CB *_*ley 27

你混淆了误导性的间距.

if (a = b || ++a == 2)
Run Code Online (Sandbox Code Playgroud)

是相同的:

if (a = (b || ((++a) == 2)))
Run Code Online (Sandbox Code Playgroud)

这实际上有未定义的行为.虽然在评估b和评估之间存在一个序列点((++a) == 2),但由于显式赋值,隐含赋值a与另一个写入之间没有序列点.a=