是指向ANSI C中定义的空指针的指针吗?

时间:2011-06-06 22:15:57

标签: c pointers null

这段代码(从真实项目中简化)是否正确?消息是否会一直打印出来?

char *cp = NULL;
char **cpp = &cp;
if(*cpp == NULL) {
    printf("I believe this will this always print. Does it?\n");
}

谢谢!

3 个答案:

答案 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会导致某种崩溃。