你对于C++属性了解多少,或许大多数人从始至终都没有见过,你甚至认为这不是c++写的代码,如
- int a [[maybe_unused]] ;
- [[deprecated("这个方法过时了!别再用了!")]] [[nodiscard("什么?你忽略返回值?!")]] int c(){}
你或许觉得很困惑,这种语法闻所未闻,一切都得参考于标准文档对此的介绍
属性说明符序列(C++11 起) - cppreference.com
属性为各种由实现定义的语言扩展(例如 GNU 与 IBM 的语言扩展
__attribute__((...)),微软的语言扩展__declspec()等)提供了统一化的语法。属性可用在 C++ 程序中的几乎所有位置,而且可应用于几乎所有事物:类型、变量、函数、名字、代码块、整个翻译单元,不过每个特定的属性都只在实现允许范围内有效:
[[expect_true]]可能是只能与 if,而非与类声明一同使用的属性,[[omp::parallel()]]可能是应用到代码块或 for 循环,而非到类型int等的属性。(请注意以上两个属性只是虚构的例子,有关标准与一些非标准属性请见下文)在声明中,属性既可以在整个声明之前出现,也可以直接跟在被声明实体的名字之后,这些情况下它们被组合起来。大多数其他情形中,属性应用于直接位于其之前的实体。
虽然 alignas 说明符拥有不同的语法,但它是属性序列说明符的一部分。它可以在
...属性出现的地方出现,并可以和它们混合(假设此处允许使用 alignas)两个连续的方括号记号(
[[)只能在引入属性说明符的地方出现,或在属性实参之内。
不说编译器扩展,我们至少要清楚标准库的C++属性
标准属性
C++ 标准仅定义下列属性。
[[noreturn]](C++11 起)指示函数不返回 [[carries_dependency]](C++11 起)指示释放消费 std::memory_order 中的依赖链传入和传出该函数。 [[deprecated]](C++14 起)[[deprecated("原因")]](C++14 起)指示允许使用声明有此属性的名称或实体,但因 原因 而不鼓励使用。 [[fallthrough]](C++17 起)指示从前一 case 标号直落是有意的,而在发生直落时给出警告的编译器不应该为此诊断。 [[nodiscard]](C++17 起)[[nodiscard("原因")]](C++20 起)鼓励编译器在返回值被舍弃时发布警告。 [[maybe_unused]](C++17 起)压制编译器在未使用实体上的警告,若存在。 [[likely]](C++20 起)[[unlikely]](C++20 起)指示编译器应该针对通过某语句的执行路径比任何其他执行路径更可能或更不可能的情况进行优化。 [[no_unique_address]](C++20 起)指示非静态数据成员不需要拥有不同于其类的所有其他非静态数据成员的地址。 [[optimize_for_synchronized]](TM TS)指示应该针对来自 synchronized 语句的调用来优化该函数定义
[[ using 属性命名空间 : 属性列表 ]](C++17 起)
这种语法我们先不再介绍,我们演示一些非常常用的属性
- #include
-
- /*C++ 属性: noreturn (C++11 起)指示函数不返回。
- 此属性仅应用到函数声明中正在声明的函数名。若拥有此属性的函数实际上返回,则行为未定义。
- 若函数的任何声明指定此属性,则其首个声明必须指定它。若函数在一个翻译单元中声明为带 [[noreturn]] 属性,而同一函数在另一翻译单元中声明为不带 [[noreturn]] 属性,则程序非良构;不要求诊断。*/
-
- [[ noreturn ]] void f() {
- throw "error";
- // OK
- }
- void q [[ noreturn ]] (int i) {
- // 若以 <= 0 的参数调用则行为未定义
- if (i > 0) {
- throw "positive";
- }
- }
- /*void f()表示“f返回非值”。
- [[noreturn]] void g()意思是“g根本不回来;它会做其他事情而不是返回。
- 通常没有理由使[[noreturn]]函数具有非void返回类型,但在不寻常的情况下,您可能需要这样做。
- 意思就是你可以写一个[[noreturn]] int g(),为了通过编译你需要return一个值,但是这并不一定导致UB,因为你可以让这个函数一直不return,比如死循环,或者运行完了直接exit(0),throw
- void类型的函数一样如此,不能正常的使用和结束
- */
-
- [[nodiscard("什么?你忽略返回值?!")]] int n(int i) {//鼓励编译器在返回值被舍弃时发布警告c++17,带参数的是c++20
- return i;
- }
- [[deprecated("这个方法过时了!别再用了!")]] [[nodiscard("什么?你忽略返回值?!")]] int c() {//指示声明有此属性的名字或实体被弃用,即允许但因故不鼓励使用。
- return 0;
- }
-
- int main() {
- int a [[maybe_unused]] ;//压制编译器在未使用实体上的警告,若存在(c++17)。(如果没有使用这个属性说明符那么就会“a:未引用的局部变量”)
- int b;//对照组
- n(10);
- c();
- }
我们需要看注释,对这些“属性”的解释,你们需要理解noreturn属性的意义,顺带一提
标准库
下列标准函数声明带有
noreturn属性:
终止函数
(C++11)
导致正常的程序终止,不进行清理
(函数)导致非正常的程序终止(不进行清理)
(函数)导致正常的程序终止并进行清理
(函数)(C++11)
导致快速程序终止,不进行完全的清理
(函数)异常处理失败时调用的函数
(函数)(C++17 中移除)
违背动态异常说明时调用的函数
(函数)始终抛出异常的函数
(C++11)
从一个 std::exception_ptr 抛出异常
(函数)抛出其所存储的异常
(std::nested_exception的公开成员函数)(C++11)
抛出实参,带上混入的 std::nested_exception
(函数模板)非局部跳转 (C++17 起)
跳转到指定位置
(函数)
一切皆以文档为准即可,c++属性的使用实际也非常的简单有意思