我什么时候使用 "__attribute__((nonnull))" vs "not_null<T*>"?
When do I use "__attribute__((nonnull))" vs "not_null<T*>"?
我习惯于在表达不应该为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函数1(gsl::not_null<int*>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))
吗?
我一直认为编译器属性可能有助于优化,但包装器版本解析为未分配的指针。
"我现在应该一直使用not_null来代替属性((nonnull))吗?
not_null
似乎是更好的方法,原因如下:
__attribute__((nonnull))
似乎是特定于gcc的,所以这意味着只有gcc可以将此属性用于优化、安全性、安全性和静态代码分析器(等等,你能想到的)。如果要使用多个编译器,这就不是一个很好的选择。例如,微软有__assume
,它可以用来实现类似的结果。
gsl::not_null
不是标准模板库的一部分,因此不能保证它以相同的方式在所有编译器上工作。您可能会发现,在某些编译器上,它绝对不会有什么特别的作用。然而,这是一个更好的选择,因为not_null
可以封装所有编译器变体以获得相同的结果(还可以添加运行时检查)。但从目前的实现来看(见链接),只支持使用__assume
的Microsoft编译器(找不到gcc的实现,但如果你有,那么使用它是一个优势)
相关文章:
- 什么时候调用组成单元对象的析构函数
- 什么时候在C++中返回常量引用是个好主意
- 什么时候调用析构函数
- boost odeint什么时候真正调用观测者
- 编译器对数组声明大小的计算。什么时候发生?
- 什么时候最好在子进程中使用 CPU 或 I/O 密集型代码 [ C++ ]
- 您应该在什么时候创建自己的异常类型
- 我什么时候会默认(而不是删除)基类中的复制和移动操作
- 什么时候可以使用常量装饰调用我的重载函数?
- unordered_map什么时候返回 -1?
- QCoreApplication什么时候有效?
- sizeof(size_t) 和 sizeof(ptrdiff_t) 什么时候会有所不同?
- 什么时候用指针调用C++类构造函数
- 我不明白在这个例子中什么时候调用构造函数
- 如果真的需要std::move,我们应该什么时候声明右值refs
- P1008("prohibit aggregates with user-declared constructors")在实践中什么时候有用?
- 程序什么时候会创建多个堆
- 调用boost.asio的异步函数时,线程是什么时候创建的
- Swig/python : 什么时候需要 SWIG_init() ?
- 什么时候 std::initializer_list 是微不足道的可构造的?