C++ Attribute 属性说明符

目录

  • 属性说明符 Attribute
    • 编译警告相关
      • [[deprecated]]
      • [[maybe_unused]]
      • [[fallthrough]]
      • [[nodiscard]]
    • 可能触发编译优化
      • [[noreturn]]
      • [[likely]]、[[unlikely]]
      • [[assume]]
      • [[carries_dependency]]
      • [[no_unique_address]]

属性说明符 Attribute

属性说明符Attribute自C++11起,允许程序员给编译器提供额外的信息让其对程序进行优化、检查、约束。

它并不是新东西,各家编译器本来就有自带的各种属性,标准属性把一些经典的属性给标准化了

编译警告相关

这类属性和编译期警告有关,不会影响最终编译出的程序。

  • 可以打开和关闭

  • 最为常用,且不容易出错的属性。

[[deprecated]]

指示声明有此属性的名字或实体被弃用,即允许但因故不鼓励使用。实体包括类型(struct,class,union)、别名、变量、非静态数据成员、函数、命名空间,枚举类型、枚举类型中的一项、模版特化这些实体。

使用案例:

[[deprecated("Please use int foo2()")]]int foo() { return 2;}

如果调用foo函数,编译器就会报警告:

<source>:9:15: warning: 'int foo()' is deprecated: Please use int foo2() [-Wdeprecated-declarations]9 |     return foo();|            ~~~^~

[[maybe_unused]]

抑制对未使用实体的警告。

实体包括类型(struct,class,union)、别名、变量、非静态数据成员、函数、命名空间,枚举类型、枚举类型、结构化绑定。

典型的场景是关闭一些因为log级别变化而产生未使用变量编译警告:

#ifdef ENABLE_DEBUG_LOG
#define LOG_DEBUG(x)  {  std::cout <<"D: " << x <<"\n";}
#else
#define LOG_DEBUG(x) // nothing
#endifint foo() {[[maybe_unused]]const char* errorMessage="Wrong";// 生产环境中debug级别的日志不会被打印,所以errorMessage实际上是不会被使用的LOG_DEBUG(errorMessage)return 0;
}

[[fallthrough]]

指示switch语句中从前一标号直落是有意的,而在发生直落时给出警告的编译器不应诊断它。

void f(int n)
{int local{0};switch (n){case 1:case 2:local += 1;[[fallthrough]];case 3: // 直落时不警告local *= 2;case 4:while (false){[[fallthrough]]; // 非良构:下一语句不是同一迭代的一部分}case 6:[[fallthrough]]; // 非良构:没有后继的 case 或 default 标号}
}

[[nodiscard]]

可被用于函数声明、类声明、枚举类型声明中。

不是 void 的 弃值表达式(discarded-value expression)(即非返回值未被接收的表达式)中,则鼓励编译器发布警告。

调用声明为 nodiscard 的函数,或

调用按值返回声明为 nodiscard 的枚举或类的函数,或

以显式类型转换或 static_cast 形式调用声明为 nodiscard 的构造函数,或

以显式类型转换或 static_cast 形式构造声明为 nodiscard 的枚举或类的对象,

它有好几个使用场景:

  • 迫使程序员检查错误码,如下:
enum class[[nodiscard]] ErrorCode {Success,Wrong
};// 当调用该函数却没有检查其返回值时,会报编译警告
ErrorCode foo() {return ErrorCode::Success;
}
  • 警告资源泄露,比如程序员分配了内存却不使用它,这会造成资源泄露。

    因此operator newnodiscard 的属性。

另一个使用场景是警告调用错误,比如在对C++容器不熟悉的程序员很容易将容器的成员函数empty()认为是清空容器,因此几乎所有容器的empty() 成员函数都有nodiscard属性,一旦发生调用该函数却不检查返回值,大概率是empty()被错误使用了。

可能触发编译优化

这类属性可能触发编译优化,这些优化会影响最终编译出来的程序。这些属性可能会引发程序错误,谨慎使用。

[[noreturn]]

编译器会根据这个属性对程序进行优化,比如会直接忽略在该函数之后的代码。

  • 告诉编译期函数不会返回,直接终止程序。
  • 如果该函数返回,那么程序行为未定义。

[[likely]]、[[unlikely]]

允许编译器为包含该语句的执行路径,比任何其他不包含该语句的执行路径,更可能或更不可能的情况进行优化。

  • 可用于if语句
  • 可用于switch语句

编译器可能会根据该属性更改代码布局,比如对instruction cache更加友好。它不会影响芯片的分支预测功能,貌似没有指令可以指导分支预测电路。

[[assume]]

指示表达式在给定的位置永远会求值为true,编译器会根据该属性进行编译优化。

假设在不成立时会导致未定义行为,所以不建议使用。

[[carries_dependency]]

用来传递std::memory_order中release-consume的依赖链进入函数,这允许编译器跳过不必要的内存栅栏指令。

不推荐使用,甚至有专门的P0371R1: Temporarily discourage memory_order_consume用来传递std::memory_order中release-consume的依赖链进入函数,这允许编译器跳过不必要的内存栅栏指令。不推荐使用paper。

[[no_unique_address]]

允许此数据成员与其类的其他非静态数据成员或基类子对象重叠。

可以用来优化空类成员变量,编译器可将它优化为不占空间,就像空基类优化一样。

struct Empty {};
// 使用空基类优化
struct EmptyBaseOptimization: public Empty {int i;
};
struct Foo_noOpt {Empty empty;int i;
};
// 使用[[no_unique_address]]
struct Foo_Opt {[[no_unique_address]] Empty empty;int i;
};int main() {// 空类也是有大小的static_assert(sizeof(Empty) == 1);// 空基类优化会使得空基类不占用空间static_assert(sizeof(EmptyBaseOptimization) == 4);// 空类的成员也会占用内存空间,为了对齐,占据四个字节static_assert(sizeof(Foo_noOpt) == 8);// Foo_Opt对空类成员使用了[[no_unique_address]]属性,它被优化掉了static_assert(sizeof(Foo_Opt) == 4);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/70512.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

openEuler部署 sysstat工具

查看环境 [rootlocalhost lxm]# cat /etc/os-release NAME"openEuler" VERSION"23.09" ID"openEuler" VERSION_ID"23.09" PRETTY_NAME"openEuler 23.09" ANSI_COLOR"0;31"查看 yum 源 [rootlocalhost lxm]# he…

第八届大数据与应用统计国际学术研讨会(ISBDAS 2025)

重要信息 官网&#xff1a;www.is-bdas.org 时间&#xff1a;2025年2月28-3月2日 地点&#xff1a;中国 广州 主办单位&#xff1a;广东省高等教育学会人工智能与高等教育研究分会 协办单位&#xff1a;北京师范大学人工智能与未来网络研究院、人工智能与大数据科研基地 …

Dify使用

1. 概述 官网:Dify.AI 生成式 AI 应用创新引擎 文档:欢迎使用 Dify | Dify GITHUB:langgenius/dify: Dify is an open-source LLM app development platform. Difys intuitive interface combines AI workflow, RAG pipeline, agent capabilities, model management, ob…

认识O(NlogN)的排序

归并排序 归并排序&#xff08;任何一个递归&#xff09;如果不懂可以画一个树状结构去帮助自己去理解。 核心排序方法为Merger public class 归并排序 {public static void main(String[] args) {int[] arr1 {3, 1, 2, 2, 5, 6};int[] arr2 Arrays.copyOf(arr1, arr1.len…

方波的基波和谐波详细推导,以及matlab验证[电路原理---2]

最近要滤波&#xff0c;从1KHZ 方波中获得正弦波&#xff0c;这让我们要对方波的频谱有具体的了解。虽然楼主一年前刚学过傅里叶。但也是忘的干干净净查阅资料后终于是整理出来。用漂亮的latex打出来了&#xff0c;为自己留存一份记录&#xff0c;也分享给大家学习。 方波的基…

计算机组成原理(3)

计算机组成原理&#xff08;3&#xff09; 存储器层次结构存储器概述存储器分类存储器性能指标 半导体随机存储SRAM和DRAM 存储器层次结构 主存-辅存&#xff1a;实现了虚拟存储系统&#xff0c;解决了主存容量不足的问题&#xff1b; Cache-主存&#xff1a;解决了主存于CPU速…

2024最新版Java面试题及答案,【来自于各大厂】

发现网上很多Java面试题都没有答案&#xff0c;所以花了很长时间搜集整理出来了这套Java面试题大全~ 篇幅限制就只能给大家展示小册部分内容了&#xff0c;需要完整版的及Java面试宝典小伙伴点赞转发&#xff0c;关注我后在【翻到最下方&#xff0c;文尾点击名片】即可免费获取…

DeepSeek-V3 论文解读:大语言模型领域的创新先锋与性能强者

论文链接&#xff1a;DeepSeek-V3 Technical Report 目录 一、引言二、模型架构&#xff1a;创新驱动性能提升&#xff08;一&#xff09;基本架构&#xff08;Basic Architecture&#xff09;&#xff08;二&#xff09;多令牌预测&#xff08;Multi-Token Prediction&#xf…

编程中的科学计数法

目录 1. 科学计数法的基本格式 2. 在代码中使用科学计数法 &#xff08;1&#xff09;直接赋值 &#xff08;2&#xff09;输出科学计数法 3. 科学计数法的底层存储 4. 输入科学计数法 5. 科学计数法的精度问题 6. 应用场景 7. 注意事项 8. 总结 编程中的科学计数法&…

2025.2.7 Python开发岗面试复盘

2025.2.7 Python开发岗面试复盘 问题: 是否了解过其他语言? 了解过Java、JavaScript、C等语言,但主要技术栈是Python。 Python跟Java的区别? Python是解释型语言,Java是编译型语言 Python动态类型,Java静态类型 Python简洁易读,Java相对严谨复杂 Python GIL限制并发,Java并…

Mac 基于Ollama 本地部署DeepSeek离线模型

最近节日期间最火的除了《哪吒》就是deepseek了&#xff0c;毕竟又让西方各个层面都瑟瑟发抖的产品。DeepSeek凭借其强大的AI能力真的是在全球多个领域展现出强大的影响力。由于受到外部势力的恶意攻击倒是deepseek官方服务不稳定&#xff0c;国内其他厂家的适配版本也不是很稳…

51单片机之引脚图(详解)

8051单片机引脚分类与功能笔记 1. 电源引脚 VCC&#xff08;第40脚&#xff09;&#xff1a;接入5V电源&#xff0c;为单片机提供工作电压。GND&#xff08;第20脚&#xff09;&#xff1a;接地端&#xff0c;确保电路的电位参考点。 2.时钟引脚 XTAL1&#xff08;第19脚&a…

Android双屏异显Presentation接口使用说明

在点餐、收银、KTV等场景,对于双屏异显的需求是非常多的,首先可以节省硬件成本。而现在的智能板卡很多运行Android系统,从Android4.2开始支持WiFi Display(Miracast)功能后,就开始支持双屏异显Presentation这套应用层接口了,下面以Android5.1系统来说明这套接口的使用要…

力扣刷题 题11,12

题目11 思路&#xff1a;设置左右指针 left和 right 指针指向数组的开始和末尾&#xff0c;max_water 用于记录最大容量初始为0。利用while循环left<right&#xff0c;移动指针比较数组元素 height[left] 和 height[right] 的大小&#xff0c;移动较短的那条线的指针&#x…

使用Python实现PDF与SVG相互转换

目录 使用工具 使用Python将SVG转换为PDF 使用Python将SVG添加到现有PDF中 使用Python将PDF转换为SVG 使用Python将PDF的特定页面转换为SVG SVG&#xff08;可缩放矢量图形&#xff09;和PDF&#xff08;便携式文档格式&#xff09;是两种常见且广泛使用的文件格式。SVG是…

爬虫工程师分享:获取京东商品详情SKU数据的技术难点与攻破方法

在电商数据领域&#xff0c;京东商品详情页的SKU数据是许多爬虫工程师的目标。这些数据包含了商品的价格、库存、规格等关键信息&#xff0c;对于市场分析、价格监控等应用场景至关重要。然而&#xff0c;获取这些数据并非易事&#xff0c;京东作为国内电商巨头&#xff0c;其反…

【DeepSeek × Postman】请求回复

新建一个集合 在 Postman 中创建一个测试集合 DeepSeek API Test&#xff0c;并创建一个关联的测试环境 DeepSeek API Env&#xff0c;同时定义两个变量 base_url 和 api_key 的步骤如下&#xff1a; 1. 创建测试集合 DeepSeek API Test 打开 Postman。点击左侧导航栏中的 Co…

kamailio中路由模块汇总

功能模块描述请求路由 (request_route)主要处理进入的SIP请求&#xff0c;包含初步检查、NAT检测、CANCEL请求处理、重传处理等。处理通过REQINIT、NATDETECT、RELAY等子模块的调用。CANCEL处理对CANCEL请求进行处理&#xff0c;包括更新对话状态并检查事务。如果事务检查通过&…

使用java代码操作rabbitMQ收发消息

SpringAMQP 将来我们开发业务功能的时候&#xff0c;肯定不会在控制台收发消息&#xff0c;而是应该基于编程的方式。由于RabbitMQ采用了AMQP协议&#xff0c;因此它具备跨语言的特性。任何语言只要遵循AMQP协议收发消息&#xff0c;都可以与RabbitMQ交互。并且RabbitMQ官方也…

【非 root 用户下全局使用静态编译的 FFmpeg】

在非 root 用户下全局使用静态编译的 FFmpeg&#xff0c;可以按照以下方法操作&#xff1a; 1. 下载静态编译的 FFmpeg 如果你还没有下载静态编译的 FFmpeg&#xff0c;可以从官方网站获取&#xff1a; wget https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd6…