[[noreturn]]是C++11引入的标准属性,用于声明函数永不返回,非宏非注释,影响编译器优化与诊断;误标(如含return语句)将导致编译错误,必须置于函数声明紧前方。

[[noreturn]] 这类双中括号是 C++11 引入的标准属性语法
它不是宏、不是注释、也不是编译器扩展,而是语言级的标准化标注机制,用于向编译器传达语义信息。编译器可据此做优化、检查或生成警告,但不改变程序运行逻辑。
常见标准属性及其典型用途
标准属性必须写在声明或定义的**紧前方**(可带空格或换行),且每个属性需独立成对 [[]]:
-
[[noreturn]]:标记函数永不返回(如std::abort()、throw后无catch的函数)。误标会导致未定义行为,编译器可能报错或静默忽略 -
[[nodiscard]]:提示调用者不应忽略该函数的返回值。对[[nodiscard]] int foo();写foo();可能触发警告(取决于编译器和警告级别) -
[[maybe_unused]]:抑制“变量/参数未使用”的警告,常用于调试宏或跨平台条件编译中暂时不用的形参 -
[[deprecated]]:标记名称已弃用,如[[deprecated("use bar() instead")]] void foo();,调用时触发警告
双中括号和宏、注释、自定义属性的区别
容易混淆的点:
- 不是宏:
[[]]不参与预处理,不能用#define模拟;写成#define MY_ATTR [[noreturn]]是合法的,但本质仍是标准属性,不是宏展开逻辑 - 不是注释:注释会被预处理器删除,而
[[]]保留在语法树中,影响语义(比如[[noreturn]]函数内写return;是非法的) - 非标准属性可能被忽略:如
[[gnu::always_inline]]是 GCC 扩展,Clang 可能识别,MSVC 则不认;而[[noreturn]]在所有符合 C++11+ 的编译器中行为一致 - 不能嵌套或省略空格:
[ [noreturn] ](带空格)或[[noreturn][[deprecated]](缺逗号)都是非法的;多个属性要写成[[noreturn, deprecated]]或分开写[[noreturn]] [[deprecated]]
实际编码中容易踩的坑
几个真实发生过的错误场景:
立即学习“C++免费学习笔记(深入)”;
- 把
[[noreturn]]加在有return语句的函数上——编译器(如 GCC 12+)会直接报错,而非警告 - 在类成员函数声明中漏掉
const位置:[[nodiscard]] int get() const;正确;int get() [[nodiscard]] const;是语法错误 - 误以为
[[maybe_unused]]能屏蔽未初始化警告——它只管“未使用”,不管“未初始化”。int x [[maybe_unused]];仍会触发 -Wuninitialized(若启用) - 在模板参数列表里乱用:属性不能出现在
template<typename T [[maybe_unused]]>这种位置,C++ 标准禁止
属性本身不改变内存布局或调用约定,但编译器依赖它做控制流分析——这点在静态分析工具和 sanitizer 配合时尤为关键,容易被忽略。


















