現代 C (C11/C17/C23)

nullptr 與 nullptr_t(空指標常數)

/ NULL-pointer /

數十年來,C 程式設計師用 NULL 表示「指向無物的指標」,但 NULL 只是一個巨集,常展開成整數 0(或 ((void*)0))。因為它可能是純整數,NULL 有時會在令人意外的地方表現得像數字零——例如透過可變引數函式傳遞時。C23 引入 nullptr,這是空指標常數的專用關鍵字,有自己的型別,消除了那種模稜兩可。

nullptr 是一個預定義常數,其型別為 nullptr_t(宣告於標準標頭檔)。它能乾淨地轉換成任何指標型別,與空指標比較時相等,但它「不是」整數,所以在預期數字的情境中不會被誤認為值 0。實際好處出現在可變引數函式與 _Generic:把 nullptr 傳給像 execl(...) 這種需要空指標結尾標記的函式,在每個平台上大小與型別都正確,而傳純 0 可能傳入一個比指標窄的 int 並破壞該呼叫。當你只想接受空常數時,也可以宣告型別為 nullptr_t 的參數或變數。

它是一項小而實在的安全與清晰度改進:nullptr 明確地說「空指標」,而 NULL 可能說的是「整數零」。誠實的註記:NULL 不會消失,一般的賦值與比較仍可用;nullptr 主要在角落情況——可變引數呼叫、型別泛型程式碼、類多載分派——掙得它的價值,那裡 NULL 的整數性正是錯誤所在。

char *p = nullptr; // 有型別的空指標,不是整數 0 if (p == nullptr) { /* ... */ } // 在每個平台上大小都正確的可變引數結尾標記: execl("/bin/ls", "ls", nullptr); // 此處用純 0 可能傳入過窄的 int

nullptr 的型別是 nullptr_t 而非 int,所以在可變引數呼叫中它是安全的結尾標記,那裡純 0 可能寬度不對。

NULL 在一般賦值與測試中仍可用;nullptr 真正的價值在可變引數呼叫與型別泛型程式碼,那裡 NULL 的整數性是潛藏的錯誤。

又稱
null pointer constanttyped null型別化空指標