Tre*_*key 6 c++ null attributes pointers cpp-core-guidelines
我习惯于__attribute__((nonnull))在表达不应该为null的指针时使用.
void f(int* ptr __attribute__((nonnull)));
int main(){
int* ptr = new int(1);
f(ptr);
}
void f(int* ptr){/*impl*/}
Run Code Online (Sandbox Code Playgroud)
但是,对于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*/}
Run Code Online (Sandbox Code Playgroud)
假设有语言设施支持GSL版本,我应该总是not_null<T*>代替__attribute__((nonnull))现在使用吗?
我一直认为编译器属性可能有助于优化,但包装器版本可以解析为未归因的指针.
“我现在应该总是使用 not_null 代替属性(( nonnull )) 吗?
not_null 似乎是更好的方法,原因如下:
__attribute__((nonnull))似乎是特定于 gcc 的,所以这意味着只有 gcc 可以使用这个属性进行优化、安全、安全、静态代码分析器(等等,你说出来的)。如果您想使用多个编译器,这使得它不是一个很好的选择。微软有例如__assume它可以用来实现类似的结果。
gsl::not_null不是标准模板库的一部分,因此不能保证它会以相同的方式在所有编译器上工作。您可能会发现在某些编译器上它绝对不会做任何特别的事情。然而,这是一个更好的选择,因为not_null可以包装所有编译器变体以获得相同的结果(也可以添加运行时检查)。但是从当前的实现(见链接)来看,只支持使用 Microsoft 编译器__assume(找不到 gcc 的实现,但如果你有一个,那么使用它是一个优势)