0

0

C++中的属性(Attributes, [[nodiscard]])是什么?(如何辅助编译器检查)

裘德小鎮的故事

裘德小鎮的故事

发布时间:2026-02-17 04:43:19

|

918人浏览过

|

来源于php中文网

原创

[[nodiscard]] 是编译器静态检查辅助属性,提示函数返回值不应被忽略,不改变运行时行为;c++17引入,需编译器支持并启用相应警告选项。

c++中的属性(attributes, [[nodiscard]])是什么?(如何辅助编译器检查)

[[nodiscard]] 是编译器的“提醒开关”,不是运行时约束

它告诉编译器:这个函数的返回值不该被忽略;如果调用了却没用上返回值,就报警告(或错误,取决于编译器设置)。它不改变函数行为,也不影响生成的机器码,纯粹是静态检查辅助。

常见错误现象:[[nodiscard]] int parse_int(const std::string& s); 被写成 parse_int("42");(没接返回值),GCC/Clang 默认只发警告,容易被忽视;MSVC 默认更严格,可能直接报错。

  • 使用场景:资源获取(std::unique_ptr 构造)、状态转换(std::optional::value_or())、错误码返回(自定义 Result<t></t> 类型)
  • 参数差异:它本身不接受参数,但可以和 [[nodiscard("reason")]] 一起用(C++20),让警告信息更具体,比如 [[nodiscard("ownership transferred")]]
  • 兼容性影响:C++17 引入,老项目若用 C++14 编译会直接报错;需确保构建系统设对 -std=c++17 或更高

自己加 [[nodiscard]] 前先确认返回值真有语义意义

乱加反而会干扰开发者——比如 [[nodiscard]] bool is_valid() const 被调用却不检查,确实该警告;但 [[nodiscard]] size_t size() const 被忽略(比如只用于断言),就显得啰嗦。

实操建议:

立即学习C++免费学习笔记(深入)”;

  • 优先加在「调用后不消费返回值会导致逻辑缺陷」的地方:如内存分配、错误传播、新对象构造
  • 避免加在纯访问器(accessor)上,除非该访问器有副作用或隐含状态变更(罕见)
  • 第三方库已加的(如 std::vector::data() 在 C++20 后加了),别覆盖;自己封装时可继承属性:[[nodiscard]] auto get_ptr() { return vec.data(); } 不自动继承,得显式写

警告不触发?检查编译器级别和诊断开关

写了 [[nodiscard]] 却没警告,大概率是编译器没开对应检查,或者版本太低。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

下载

常见原因:

  • 编译器版本不够:GCC 7+、Clang 4+、MSVC 2017 15.3+ 才支持;旧版识别不了,直接跳过
  • 没启用警告:GCC/Clang 默认只开 -Wall 不包含 nodiscard 检查,需额外加 -Wunused-result(GCC)或 -Wunused-result(Clang)
  • 用了 static_cast<void></void> 或逗号表达式“消音”:(void)func();(func(), 0); 会绕过检查,这是有意为之的豁免方式,不是 bug

和返回类型强相关的陷阱:auto + [[nodiscard]] 容易漏掉

auto 推导返回类型时,如果忘了写 [[nodiscard]],属性不会自动附着到推导出的类型上——它只属于函数声明本身。

错误写法:

auto create_resource() { return std::make_unique<T>(); } // ❌ 没属性

正确写法:

[[nodiscard]] auto create_resource() { return std::make_unique<T>(); } // ✅

更隐蔽的问题:模板函数中,[[nodiscard]] 必须写在每个特化或显式实例化前,不能只靠主模板带过去;SFINAE 或 requires 子句不影响属性绑定位置。

容易被忽略的是:当函数返回 [[nodiscard]] 类型(如 std::expected)时,不等于函数本身有该属性——仍需手动标注,否则调用点不会受检。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

750

2023.08.02

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

547

2023.09.20

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

750

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

570

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

234

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

209

2025.08.29

javascriptvoid(o)怎么解决
javascriptvoid(o)怎么解决

javascriptvoid(o)的解决办法:1、检查语法错误;2、确保正确的执行环境;3、检查其他代码的冲突;4、使用事件委托;5、使用其他绑定方式;6、检查外部资源等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

183

2023.11.23

java中void的含义
java中void的含义

本专题整合了Java中void的相关内容,阅读专题下面的文章了解更多详细内容。

115

2025.11.27

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

283

2026.02.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 9.6万人学习

C 教程
C 教程

共75课时 | 4.8万人学习

C++教程
C++教程

共115课时 | 18万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号