我习惯于在表达不应为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))
吗?
我一直认为编译器属性可能有助于优化,但包装器版本会解析为未归因的指针。
答案 0 :(得分:3)
&#34;我现在应该总是使用not_null代替属性((非空))吗?
not_null
似乎是更好的方法,这就是原因:
__attribute__((nonnull))
似乎是特定于gcc的,因此这意味着只有gcc可以将此属性用于优化,安全性,安全性,静态代码分析器(等等,您可以命名)。如果你想使用多个编译器,这不是一个很好的选择。例如,Microsoft可以使用__assume
来获得类似的结果。
gsl::not_null
不是标准模板库的一部分,因此无法保证它能以相同的方式在所有编译器上运行。您可能会发现在某些编译器上它绝对没有什么特别之处。但是这是一个更好的选择,因为not_null
可以包装所有编译器变体以实现相同的结果(也可以添加运行时检查)。但从当前的实现(参见链接)来看,只有使用__assume
的Microsoft编译器支持(找不到gcc的实现,但如果你有一个,那么使用它的优势)