通常如果function是在接受reference的參數, 不像是pointer 需要去檢查是不是NULL,但是下面這種情況卻會造成segmentation fault.
原因是因為deference NULL pointer (ex: *p) 本身就是未定義行為, 而NULL reference只可能出現在未定義行為的地方.
#include < stdio.h >
struct obj
{
int t;
};
void foo(obj &a)
{
std::cout << a.t;
}
int main()
{
obj *p = NULL;
foo(*p);
return 0;
}
以下的程式就算我把foo裡面的std::cout comment掉, 並且用-O0, 他就不會造成crash, 造理來說*p應該就要crash,
這邊可以看一下輸出的assembly, 就可以理解其實底層實做reference 也是用到pointer, 所以只要沒有真的access NULL pointer, 是不會造成crash
#include <stdio.h>
struct obj
{
int t;
};
void foo(obj &a)
{
}
int main()
{
obj *p = NULL;
foo(*p);
return 0;
}
可以看到main裡面assembly, 他其實也只是把pointer當參數傳進去~
movq $0, -8(%rbp)
movq -8(%rbp), %rax
movq %rax, %rdi
call _Z3fooR3obj
雖然可以透過下面的方式去檢查, 但是我覺得這樣寫很奇怪, 畢竟問題不是在foo function.
#include <stdio.h>
struct obj
{
int t;
};
void foo(obj &a)
{
if( &a == NULL) {
std::cout << "null\n";
return;
}
std::cout << a.t;
}
int main()
{
obj *p = NULL;
foo(*p);
return 0;
}
所以只有caller需要自己去檢查傳進去的pointer是不是NULL
Reference:
http://stackoverflow.com/questions/4364536/c-null-reference
http://www.nicollet.net/2009/11/can-references-be-null/
http://discuss.fogcreek.com/joelonsoftware/default.asp?cmd=show&ixPost=17154
沒有留言:
張貼留言