这段代码(从真实项目中简化)是否正确?消息是否会一直打印出来?
char *cp = NULL;
char **cpp = &cp;
if(*cpp == NULL) {
printf("I believe this will this always print. Does it?\n");
}
谢谢!
答案 0 :(得分:6)
您显示的代码没有任何问题。你的char **
指针指向一个有效的变量,因此取消引用它总是合适的。
P.S。是的,它将始终打印。
答案 1 :(得分:4)
是的,它会一直打印。
您可以放心地假设您的基础stack pointer从不指向0x0,因此& cp将始终不等于NULL。
实际上编译器将在编译时消除检查,因为它知道&cp != NULL
。
亲眼看看:
使用-O1
编译:
$ objdump -dC a.out
a.out: file format elf64-x86-64
...
00000000004004f4 <main>:
4004f4: 48 83 ec 08 sub $0x8,%rsp
4004f8: bf 00 06 40 00 mov $0x400600,%edi
4004fd: e8 ee fe ff ff callq 4003f0 <puts@plt>
400502: b8 00 00 00 00 mov $0x0,%eax
400507: 48 83 c4 08 add $0x8,%rsp
40050b: c3 retq
(-O0
会有一个测试,但是:)
00000000004004f4 <main>:
4004f4: 55 push %rbp
4004f5: 48 89 e5 mov %rsp,%rbp
4004f8: 48 83 ec 10 sub $0x10,%rsp
4004fc: 48 c7 45 f0 00 00 00 movq $0x0,-0x10(%rbp)
400503: 00
400504: 48 8d 45 f0 lea -0x10(%rbp),%rax
400508: 48 89 45 f8 mov %rax,-0x8(%rbp)
40050c: 48 8b 45 f8 mov -0x8(%rbp),%rax
400510: 48 8b 00 mov (%rax),%rax
400513: 48 85 c0 test %rax,%rax
400516: 75 0a jne 400522 <main+0x2e>
400518: bf 20 06 40 00 mov $0x400620,%edi
40051d: e8 ce fe ff ff callq 4003f0 <puts@plt>
400522: b8 00 00 00 00 mov $0x0,%eax
400527: c9 leaveq
400528: c3 retq
答案 2 :(得分:0)
当然,总会打印,为什么不打印?
您在if()
语句中取消引用的指针是cpp
。您只能使用一个*
星号取消引用一个级别。 cpp
可能指向NULL
指针,但cpp
本身不是NULL
。
另一方面,写char k = **cpp
会导致某种崩溃。