2011年7月28日 星期四

[C++] NULL reference and NULL pointer deference

通常如果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