2016-07-28 6 views
5

ヌルであってはならないポインタを表現するときは、私は__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*/} 

言語機能は、私はいつも今__attribute__((nonnull))の代わりにnot_null<T*>を使用する必要があり、GSLのバージョンをサポートするために存在していると仮定すると?

私は、コンパイラ属性が最適化を助けているかもしれないが、ラッパーバージョンが非アトリビュートポインタに解決されるという印象を受けました。 「私はいつも属性((非NULL))の代わりにNOT_NULLを使用する必要があります

+2

1つの質問は、 '__attribute __ (nonnull)) '主要なコンパイラ間で移植可能? – WhiZTiM

+0

リファレンスや 'span'を使わないのはなぜですか? – Jarod42

答えて

2

not_nullなぜここより良いアプローチとは思わ:?は

__attribute__((nonnull))があると思われますこれは、gccだけがこの属性を最適化、安全性、セキュリティ、静的コードアナライザなどに使用できることを意味します(これは、名前を付けます)。同様の結果を達成するために使用することができる10。

gsl::not_nullは標準テンプレートライブラリには含まれていないため、すべてのコンパイラで同じように動作するという保証はありません。いくつかのコンパイラでは、特別なことはまったくありません。しかし、これはより良い選択です。not_nullは、同じ結果を得るためにすべてのコンパイラバリエーションをラップすることができるからです(ランタイムチェックも追加できます)。しかし、現在の実装(リンクを参照)から判断すると、__assumeを使用してMicrosoftコンパイラをサポートしています(gccの実装が見つかりませんでしたが、それがあれば利点があります)

+0

gsl :: not_nullはMSVCの__assumeと同様のGCCとClangの機能を使用します。 OTOHは、非ナル属性によって実現された結果と同じ* not *である - 前者は単なるヒントであり、後者は保証である。 –

関連する問題