int (*a)[10] = NULL; // initilaized to NULL pointer
printf("a :: %pn", a); // print nil
printf("*a :: %pn", *a); // seg fault??
return 0;
我使用gcc在x86代码上执行了这段代码,它编译时没有任何错误
我期待类似的东西
a::(nil(
分段故障
但它实际上打印出
a::(nil(
*a::
为什么这里引用空指针不会导致seg错误?
通常的原因是,取消引用指向数组的指针不会读取任何内存,结果是一个具有相同地址的数组-结果只是不同的类型。
然而,这种行为是不明确的。
请注意,您使用了%p
,但您可以将%s
用于第二个(带有char (*a)[10] = NULL;
(,这将具有更未定义的行为,但是GCC/Glibcprintf
仍然会经常打印(nil)
而不是崩溃。
这是因为这是未定义的行为,任何事情都可能发生在任何编译器上,甚至是不同版本的编译器上。
您使用的是gcc,而gcc生成的代码只是将NULL(零(移动到rax,而不是segfault。
mov QWORD PTR [rbp-8], 0
mov rax, QWORD PTR [rbp-8]
mov QWORD PTR [rbp-16], rax
您可以在上看到使用不同版本的gcc的C程序的汇编程序输出
https://godbolt.org/