一、编译器的通用属性
随着C++语言的演变和编译器的发展,人们常常发现C++的标准提供的语言能力不能完全满足要求,因此各大编译器厂商为了满足客户需求,设计出一系列语言扩展来扩展语法,比较常见的就是“属性”。
“属性”是作用于实体对象(函数、变量、类型等)的额外附加信息,不同的编译器有着不同的属性语法,如GNU:
__attribute__ ((attribute-list))
而windows下采用:
__declspec ( extended-decl-modifier )
二、C++11的通用属性
C++11也引入了通用属性,语法为:
[[attribute-list]]
可以作用于类型、变量、名称、代码块等。对于作用于声明的通用属性,既可以写在声明的起始处,也可以写在声明的标识符之后。而对于作用于整个语句的通用属性,则应该写在语句起始处。而出现在以上两种规则描述的位置之外的通用属性,作用于哪个实体跟编译器具体的实现有关。
1.noreturn
用于标识不会返回的函数的。与返回值为空有很大区别,noreturn标记的函数执行后,其后的语句并不会执行。
主要用于那些不会将控制流返回到调用函数的函数,如终止程序的函数,无限循环语句的函数,抛出异常的函数等。
[[noreturn]] void abort(void) noexcept;
void DoSomething1();void DoSomething2();[[ noreturn ]] void ThrowAway() {throw "expection"; // 控制流跳转到异常处理}void Func(){DoSomething1();ThrowAway();DoSomething2(); // 该函数不可到达}
当前noreturn的使用也需要注意,否则会引起未定义的行为
#include <iostream>using namespace std;[[ noreturn ]] void Func(int i){//当参数i的值为0时,该函数行为不可估计if (i < 0)throw "negative";else if (i > 0)throw "positive";}int main(){Func(0);cout << "Returned" << endl; // 可以执行return 1; //发生崩溃}
上述例子中因为函数Func中的条件语句有悬挂(else没有处理),所以当传入0时,并不会抛出异常终止程序,与noreturn的属性冲突,执行了12行代码,但是最终在return时发生异常崩溃。
2.carries_dependency
通用属性[[ carries_dependency ]]则跟并行情况下的编译器优化有关。事实上,[[carries_dependency]]主要是为了解决弱内存模型平台上使用memory_order_consume内存顺序枚举问题