不能直接阻止,但能触发编译器警告;它提示返回值有意义、不应被忽略,是否报错取决于编译器及警告设置。
![c++的[[nodiscard]]属性有什么用? (强制检查返回值)](https://img.php.cn/upload/article/001/431/639/176853642343534.png)
[[nodiscard]] 能阻止调用者忽略返回值吗?
不能直接阻止,但能触发编译器警告(或错误,取决于编译选项)。它只是给编译器一个提示:这个函数/类型/构造函数的返回值“有意义”,不该被丢弃。是否报错,取决于你用的编译器和警告级别设置。
哪些地方可以加 [[nodiscard]]?
支持位置包括:函数声明、枚举定义、类/结构体定义、构造函数(C++20 起)、typedef / alias 声明(C++23)。最常见的是加在函数上。
-
[[nodiscard]] int parse_int(const std::string& s);—— 提示调用者检查解析是否成功 -
[[nodiscard]] std::unique_ptr—— 防止资源泄漏(忘了接管指针)create_widget(); -
[[nodiscard]] bool try_lock();—— 忽略锁是否获取成功,容易引发竞态
不加 [[nodiscard]] 会出什么问题?
典型问题是逻辑漏洞难以发现。比如:
std::vectorv = {1, 2, 3}; v.push_back(4); // 返回 void,没问题 v.insert(v.begin(), 5); // 返回 iterator,但没人用 —— 暂时无害 auto res = std::binary_search(v.begin(), v.end(), 7); // 返回 bool,但写成 std::binary_search(...);就丢了结果
更危险的是:
立即学习“C++免费学习笔记(深入)”;
-
std::fopen("data.txt", "r")忽略返回值 →nullptr指针后续解引用崩溃 -
std::fclose(fp)忽略返回值 → 不知道关闭是否失败,可能丢数据 - 自定义的
[[nodiscard]] Result被静默丢弃 → 错误未处理parse_json(...)
怎么让 [[nodiscard]] 真正起作用?
必须配合编译器警告开关:
- GCC / Clang:
-Wnarrowing -Wreturn-type -Wignored-attributes(部分版本需-Werror=unused-result或启用-Wnodiscard) - MSVC:
/wd4834(禁用该警告)或默认已启用 C++17+ 的[[nodiscard]]检查 - CMake 中建议加:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=unused-result -Wno-unused-parameter")
注意:如果函数返回 void、[[nodiscard]] 会被忽略;如果返回值是字面量(如 42)或临时对象且没绑定到引用,某些编译器也可能不警告。
最容易被忽略的是:它不检查“语义上是否该用”,只检查“语法上是否写了”。比如 (void)foo(); 或 foo(); 在有重载且某重载返回 void 时,也可能绕过检查。别把它当成银弹,而是配合代码审查和单元测试一起用。










