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.
精彩评论