我何时使用&#34; __ attribute __((nonnull))&#34; vs&#34; not_null <t *>&#34;?

时间:2016-07-28 16:05:34

标签: c++ pointers null attributes cpp-core-guidelines

我习惯于在表达不应为null的指针时使用__attribute__((nonnull))

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版本,我现在应该总是使用not_null<T*>代替__attribute__((nonnull))吗?

我一直认为编译器属性可能有助于优化,但包装器版本会解析为未归因的指针。

1 个答案:

答案 0 :(得分:3)

  

&#34;我现在应该总是使用not_null代替属性((非空))吗?

not_null似乎是更好的方法,这就是原因:

__attribute__((nonnull))似乎是特定于gcc的,因此这意味着只有gcc可以将此属性用于优化,安全性,安全性,静态代码分析器(等等,您可以命名)。如果你想使用多个编译器,这不是一个很好的选择。例如,Microsoft可以使用__assume来获得类似的结果。

gsl::not_null不是标准模板库的一部分,因此无法保证它能以相同的方式在所有编译器上运行。您可能会发现在某些编译器上它绝对没有什么特别之处。但是这是一个更好的选择,因为not_null可以包装所有编译器变体以实现相同的结果(也可以添加运行时检查)。但从当前的实现(参见链接)来看,只有使用__assume的Microsoft编译器支持(找不到gcc的实现,但如果你有一个,那么使用它的优势)