How about this example:
int main(int argc, char* argv[])
{
int a[] = { 111, 222 };
int *p = (argc > 1) ? &a[0] : nullptr;
p++;
p--;
return (p == nullptr);
}
At face value, this code says: 'If there are any command line arguments, initialise p
to point to the first member of a[]
, otherwise initialise it to null. Then increment it, then decrement it, and tell me if it's null.'
On the face of it this should return '0' (indicating p
is non-null) if we supply a command line argument, and '1' (indicating null) if we don't.
Note that at no point do we dereference p
, and if we supply an argument then p
always points within the bounds of a[]
.
Compiling with the command line clang -S --std=c++11 -O2 nulltest.cpp
(Cygwin clang 3.5.1) yields the following generated code:
.text
.def main;
.scl 2;
.type 32;
.endef
.globl main
.align 16, 0x90
main: # @main
.Ltmp0:
.seh_proc main
# BB#0:
pushq %rbp
.Ltmp1:
.seh_pushreg 5
movq %rsp, %rbp
.Ltmp2:
.seh_setframe 5, 0
.Ltmp3:
.seh_endprologue
callq __main
xorl %eax, %eax
popq %rbp
retq
.Leh_func_end0:
.Ltmp4:
.seh_endproc
This code says 'return 0'. It doesn't even bother to check the number of command line args.
(And interestingly, commenting out the decrement has no effect on the generated code.)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…