开发者

Is a pointer to a null pointer defined in ANSI C?

Is this code (simplified from a real project) correct? Will the message always print?

char *cp = NULL;开发者_如何学编程
char **cpp = &cp;
if(*cpp == NULL) {
    printf("I believe this will this always print. Does it?\n");
}

Thanks!


There is nothing wrong with the code you have shown. Your char ** pointer is pointing to a valid variable, thus it's always proper to dereference it.

P.S. Yes, it will always print.


Yes, it will always print.

You can safely assume that your base stack pointer never points to 0x0, so &cp will always not equal NULL.

In fact the compiler will eliminate the check at compile time, because it knows &cp != NULL.

See for yourself:

Compiled with -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

(With -O0 there will be a test, though:)

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


Of course that always prints, why would it not?

The pointer you are dereferencing in your if() statement is cpp. You only dereference one level, by using one * asterisk. cpp may point to a NULL pointer, but cpp is not itself NULL.

On the other hand writing char k = **cpp should result in a crash of some sort.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜