C/C++ 指針的非空判斷


一定要分得清楚C和C++的“空指針常量”不是一樣的。C標准不保證NULL等於0,所以做指針非空判斷時,應該用if(p != NULL);因為“上下文轉換到bool值”的統一性,C++就應該用if(p)。

 

 

************************************************************************************************************

 

首先呢,要明白一點兒,NULL是一個無類型的東西,而且是一個宏。而宏這個東西,從C++誕生開始,就是C++之父嗤之以鼻的東西,他推崇盡量避免宏。而在他的FAQ中,也有相應的一個關於NULL與0的解釋,也談到了這一點兒。Stroustrup: C++ Style and Technique FAQ

在C++標准中,我們可以見到一個詞語叫做null pointer constant,其實在C++11標准前,是只承認0為null pointer constant的。所以,在C++中,我們也經常能聽到一個說法,就是賦予null pointer,應該是使用0,而非NULL。而nullptr pointer constant這個詞語在C++11發布后,終於再添了一個成員,就是nullptr。而與NULL本質不同的是,nullptr是有類型的(放了在stddef頭文件中),類型是 typdef decltype(nullptr) nullptr_t; 而正是因為是有類型的,這給我們編譯器實現nullptr的時候帶來了更多細節的考慮,當然也給了使用者更多的保障,所以如果你的編譯器支持nullptr,請一定使用nullptr!


而nullptr的出現背景,其實是很簡單的,C++哲學上來說就是C++之父一直對null pointer沒有一個正式的表示感到非常不滿,而更工程的來說,就是關於重載這個問題。

void f(void*)
{
}

void f(int)
{
}

int main()
{
    f(0); // what function will be called?
}



而引入了nullptr,這個問題就得到了真正解決,會很順利的調到void f(void*)這個版本。

好了,真的以為nullptr就這樣了么? 我前面說過了nullptr是有類型的,叫做nullptr_t,這給我們編譯器實現帶來了諸多要考慮的東西,不幸的話讓我們來舉點兒奇葩例子吧!

union U { long i; nullptr_t t; }; int main() { U u; u.i = 3; printf("%ld\n",(long)u.t); // What it is? 0 or 3? } 

那么這是應該符合union語意還是nullptr的語意呢?這在標准中是沒有說的,我們也為此爭論了非常久。當然在我們編譯器的實現還是保持了nullptr的語意,結果是0。

而nullptr有類型后,還能做什么呢?那當然就是可以捕獲異常了。

int main() { try { throw nullptr; } catch(nullptr_t) { } } 

你扔一個NULL試試?看他應該用什么收,正是因為沒有類型,所以就要用它的本質類型,比如long什么的來說。你扔一個0試試?那就也不是所謂的空指針類型了,就是要用int什么的來收了。

所以,推崇nullptr是有道理的,我們在編譯器實現nullptr的時候考慮了非常非常多的細節,還有很多你們可能一直用不到的情況,我們都要用來測試,目的就是保障開發者的使用。再次那句話,如果你的編譯器支持nullptr,請一定使用nullptr!

 

references:

http://www.zhihu.com/question/22203461


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM