2016-07-28 20 views
5

我習慣於在表達不應該爲null的指針時使用__attribute__((nonnull))何時使用「__attribute __((nonnull))」vs「not_null <T*>」?

void f(int* ptr __attribute__((nonnull))); 

int main(){ 
    int* ptr = new int(1); 
    f(ptr); 
} 
void f(int* ptr){/*impl*/} 

然而,隨着GSL,還存在的not_null<T*>包裝類型。
void function1(gsl :: not_null n);

void f(gsl::not_null<int*> n); 

int main(){ 
    int* ptr = new int(1); 
    f(ptr); 
} 
void f(gsl::not_null<int*> n){/*impl*/} 

假設語言設施有支持GSL的版本,我就應該總是代替__attribute__((nonnull))現在可以使用not_null<T*>

我一直認爲編譯器屬性可能有助於優化,但包裝器版本解析爲未分配的指針。

+2

有一個問題,是'__attribute __ (非空))在主要編譯器之間移植? – WhiZTiM

+0

爲什麼不使用參考或span? – Jarod42

回答

2

「我就應該總是代替使用NOT_NULL 屬性((非空))現在

not_null似乎是更好的方法,這裏是爲什麼?

__attribute__((nonnull))似乎是gcc是特定的,所以這意味着只有gcc可以使用這個屬性來優化,安全,安全,靜態代碼分析器等等(如果你想使用多個編譯器,這並不是一個好的選擇)。 __assume可以用來實現類似的結果。

gsl::not_null不是標準模板庫的一部分,所以不能保證它能以同樣的方式在所有編譯器上工作。你可能會發現,在一些編譯器上它絕對沒有什麼特別的。然而,這是一個更好的選擇,因爲not_null可以包裝所有編譯器變體以實現相同的結果(也可以添加運行時檢查)。但從目前的實現(見鏈接)來看,僅支持使用__assume的微軟編譯器(找不到gcc的實現,但是如果你有一個,那麼使用它就有優勢)

+0

gsl :: not_null現在使用類似於MSVC的__assume的GCC和Clang的功能。 OTOH,它與非空屬性的結果*不相同 - 前者只是一個提示,後者是保證。 –

相關問題