-wunused-result 报错是因为编译器默认检查标准库中已标注[[nodiscard]]的函数(如write、fread),忽略其返回值即触发警告;需用(void)显式声明忽略意图,而非禁用警告。

为什么 -Wunused-result 会报错但你没写 [[nodiscard]]
因为 GCC/Clang 默认启用 -Wunused-result(或通过 -Wall 间接启用),对标准库中带 [[nodiscard]] 的函数(如 fread、write、std::regex_search)强制检查返回值。即使你自己没加 [[nodiscard]],调用这些函数时忽略返回值也会触发警告——这不是你的代码问题,而是编译器在帮你防错。
常见错误现象:warning: ignoring return value of ‘ssize_t write(int, const void*, size_t)’, declared with attribute nodiscard
- 不是所有函数都受此约束,只影响明确标注
[[nodiscard]]或被编译器内置规则覆盖的函数 - MSVC 默认不启用类似检查,所以跨平台项目容易漏掉这类隐患
- 警告级别高(
-Werror下直接编译失败),但禁用它等于放弃一层安全防护
忽略返回值时必须显式声明“我知道”
最稳妥的做法不是关警告,而是用 (void) 强制表明意图。这既满足编译器要求,又留下可读线索,说明此处忽略是经过判断的。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
// 正确:明确表达“我不要这个返回值” (void)write(fd, buf, len); // 错误:仍然触发警告 write(fd, buf, len); // 错误:C 风格 cast 在 C++ 中不推荐,且易被误读为“想转类型” (void)write(fd, buf, len); // ✅ 可以,但括号紧贴函数调用更清晰 static_cast<void>(write(fd, buf, len)); // ✅ 语义更 C++,但略啰嗦</void>
- 不要用
[[maybe_unused]]修饰调用结果——它只适用于变量声明,不适用于表达式 - 避免宏封装
(void),比如#define IGNORE(x) (void)(x),会掩盖真实意图,且破坏调试体验 - 如果函数返回
std::optional或自定义[[nodiscard]]类型,同样适用该规则
哪些情况真可以关掉这个警告
仅限极少数场景:比如单元测试中故意触发某个函数的副作用(如 std::this_thread::yield()),且其返回值完全无意义;或对接旧 C 库时,大量遗留调用无法一一补全 (void),临时压制。
- 局部关闭:在对应代码段前后加
#pragma GCC diagnostic ignored "-Wunused-result"(GCC)或#pragma clang diagnostic ignored "-Wunused-result"(Clang) - 全局关闭(不推荐):
-Wno-unused-result—— 这会让所有[[nodiscard]]失效,包括你自己加的 - 项目级折中:用
CMake对特定源文件禁用,例如set_source_files_properties(file.cpp PROPERTIES COMPILE_OPTIONS "-Wno-unused-result")
自己写的函数要不要加 [[nodiscard]]
要,但得看语义。如果函数的返回值承载关键状态(如是否成功、有多少字节写入、匹配是否发生),就必须加;如果只是链式调用的中间对象(如 std::vector::push_back 返回 void),则不用。
[[nodiscard]] std::expected<size_t std::error_code> safe_write(int fd, std::span<const std::byte> data); [[nodiscard]] bool try_lock(); // 成功与否是核心信息 std::vector<int>& operator+=(std::vector<int>& v, int x); // 不加:返回引用仅为支持链式,非关键状态</int></int></const></size_t>
- 加了
[[nodiscard]]后,调用方一旦忽略就会触发同等级警告,形成双向约束 - 不要给返回
void的函数加——编译器会报错 - 注意 ABI 兼容性:加
[[nodiscard]]不改变二进制接口,但会影响调用方编译行为
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










