void main()
{
int i=-3, j=2, k=0,m;
m = ++i && ++j || ++k;
printf("\n%d %d %d %d",i,j,k,m);
}此代码段打印-2 3 0 1,但为什么不打印-2 3- 1 1。即使k的++运算符优先于逻辑运算符,为什么k不会因为短路而递增?更普遍的是,当涉及到逻辑运算符和副作用时,如何应用优先?
发布于 2014-04-29 15:10:11
这里的短路表示,如果逻辑AND运算符&&的左操作数计算结果为false,则它不会计算其右操作数。同样,如果逻辑OR运算符||的左操作数的计算结果为true,则不计算其右操作数。这是因为,无论正确的操作数的计算结果如何,结果都不会受到影响。
此外,与||算子相比,&&具有更高的优先级。
因此,表达式m = ++i && ++j || ++k;等同于
m = (++i) && (++j || ++k);左操作数++i的计算结果为-2,它是true (非零)。因此,现在计算第二个表达式(++j || ++k)。||运算符的左操作数是++j,其计算结果为3,即true。这意味着不计算表达式++k的||的右操作数。
因此,仅计算子表达式++i和++j。当表达式为true时,整个表达式的计算结果为1。
发布于 2014-04-29 15:10:13
首先,主函数(除非你使用古老的Turbo )应该返回int。
其次,一个不错的编译器(对我来说是clang)抱怨这个可疑的表达式:
clang++ -S -mllvm --x86-asm-syntax=intel ls.cpp
ls.cpp:5:11: warning: '&&' within '||' [-Wlogical-op-parentheses]
m = ++i && ++j || ++k;
~~~~^~~~~~ ~~
ls.cpp:5:11: note: place parentheses around the '&&' expression to silence this warning
m = ++i && ++j || ++k;
^
( )
1 warning generated.第三,让我们看看程序集的输出:
mov dword ptr [rbp - 8], -3 # this is i
mov dword ptr [rbp - 12], 2 # this is j
mov dword ptr [rbp - 16], 0 # this is k
mov eax, dword ptr [rbp - 8] # this is i++
add eax, 1
mov dword ptr [rbp - 8], eax
cmp eax, 0 # is i++ == 0?
je .LBB0_2
# BB#1: # no, i++ is NOT 0
mov al, 1
mov ecx, dword ptr [rbp - 12] # this is j++
add ecx, 1
mov dword ptr [rbp - 12], ecx
cmp ecx, 0
mov byte ptr [rbp - 21], al # store al as a flag somewhere else
# it will be the final result of the operation
jne .LBB0_3 # if j++ was NOT zero, go down to LBB0_3
.LBB0_2: # Yes, i++ is 0. Did you remark that
# it didn't increment j in this case?
# but it needs to increment k since the first
# part of the OR evaluated to false.
mov eax, dword ptr [rbp - 16] # This is k++
add eax, 1
mov dword ptr [rbp - 16], eax
cmp eax, 0 # is c++ 0?
setne cl # if yes, set cl as a flag to 1
mov byte ptr [rbp - 21], cl # 1-byte Spill
# and here we get if j++ was not zero,
# so did you remark that k was not incremented?
.LBB0_3:
mov al, byte ptr [rbp - 21] # 1-byte Reload
lea rdi, qword ptr [.L.str]
and al, 1
movzx ecx, al
mov dword ptr [rbp - 20], ecx
# there goes the printf
mov esi, dword ptr [rbp - 8]
mov edx, dword ptr [rbp - 12]
mov ecx, dword ptr [rbp - 16]
mov r8d, dword ptr [rbp - 20]
mov al, 0
call printfhttps://stackoverflow.com/questions/23357337
复制相似问题