(C++20) consteval立即函数

文章目录

  • 由来
  • consteval立即函数
    • 上下文的常量性质
    • lambda表达式
  • 编译期间确定
    • 无法获取函数指针
    • 查看汇编
  • END

由来

在C++11中推出了constexpr使得对象或者函数能够具有常量性质并能在编译器确定。但是对于constexpr修饰的函数来说,无法保证严格的在编译器确定。

下面这段代码,fun1正常编译运行,但是到了fun2就会编译失败。

constexpr int square(int x) {return x * x;
}void fun1(int x) {square(10);square(x);
}void fun2(int x) {constexpr int num1 = square(10);// error: 'x' is not a constant expression// constexpr int num2 = square(x);
}int main(int argc, char** argv) {
}

consteval立即函数

consteval 说明符 (C++20 起) - cppreference.com

为了能够强制在编译期间计算,C++20推出了consteval关键字用于修饰函数。强制要求该函数必须表现为常量性质

consteval int square(int x) {return x * x;
}

上下文的常量性质

编译器会自动检测上下文的常量性质,因此下面这段代码也是可性的。

constexpr int square(int x) {return x * x;
}// constexpr函数 调用 constexpr函数
constexpr int re_square(int x) {return square(square(x));
}int main() {// 上下文常量性质const int     x    = 10;constexpr int num1 = square(x);constexpr int num2 = re_square(x);
}

lambda表达式

说到函数怎么能少得了lambda函数,在参数后添加关键字即可。

int main() {auto square = [](int x) constexpr { return x * x; };const int     x   = 10;constexpr int num = square(x);
}

编译期间确定

无法获取函数指针

新手可能不太了解什么叫编译期间确定。

这里举个例子,一般函数我们可以获取它的地址,并赋到一个函数指针上。

但是consteval函数不行。因为它根本不会产生函数实例!

int fun1(int x) {return x + 10;
}consteval int fun2(int x) {return x + 10;
}int main() {int (*funPtr1)(int) = &fun1;// error: taking address of an immediate function ‘consteval int fun2(int)’// int (*funPtr2)(int) = &fun2;
}

查看汇编

再具体的我们来查看汇编代码,便会一目了然!

现在有如下的代码:

int funnnnnn000000000000000000000000(int x) {return x + 10;
}constexpr int funnnnnn111111111111111111111111(int x) {return x + 10;
}consteval int funnnnnn222222222222222222222222(int x) {return x + 10;
}int main() {const int x = 10;funnnnnn000000000000000000000000(x);funnnnnn111111111111111111111111(x);funnnnnn222222222222222222222222(x);
}

环境与指令:

gcc version 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04) 
g++ -std=c++20 test.cpp -S

生成的汇编代码:

	.file	"test.cpp".text.globl	_Z32funnnnnn000000000000000000000000i.type	_Z32funnnnnn000000000000000000000000i, @function
_Z32funnnnnn000000000000000000000000i:
.LFB0:.cfi_startprocendbr64pushq	%rbp.cfi_def_cfa_offset 16.cfi_offset 6, -16movq	%rsp, %rbp.cfi_def_cfa_register 6movl	%edi, -4(%rbp)movl	-4(%rbp), %eaxaddl	$10, %eaxpopq	%rbp.cfi_def_cfa 7, 8ret.cfi_endproc
.LFE0:.size	_Z32funnnnnn000000000000000000000000i, .-_Z32funnnnnn000000000000000000000000i.section	.text._Z32funnnnnn111111111111111111111111i,"axG",@progbits,_Z32funnnnnn111111111111111111111111i,comdat.weak	_Z32funnnnnn111111111111111111111111i.type	_Z32funnnnnn111111111111111111111111i, @function
_Z32funnnnnn111111111111111111111111i:
.LFB1:.cfi_startprocendbr64pushq	%rbp.cfi_def_cfa_offset 16.cfi_offset 6, -16movq	%rsp, %rbp.cfi_def_cfa_register 6movl	%edi, -4(%rbp)movl	-4(%rbp), %eaxaddl	$10, %eaxpopq	%rbp.cfi_def_cfa 7, 8ret.cfi_endproc
.LFE1:.size	_Z32funnnnnn111111111111111111111111i, .-_Z32funnnnnn111111111111111111111111i.text.globl	main.type	main, @function
main:
.LFB3:.cfi_startprocendbr64pushq	%rbp.cfi_def_cfa_offset 16.cfi_offset 6, -16movq	%rsp, %rbp.cfi_def_cfa_register 6subq	$16, %rspmovl	$10, -4(%rbp)movl	$10, %edicall	_Z32funnnnnn000000000000000000000000imovl	$10, %edicall	_Z32funnnnnn111111111111111111111111imovl	$0, %eaxleave.cfi_def_cfa 7, 8ret.cfi_endproc
.LFE3:.size	main, .-main.ident	"GCC: (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0".section	.note.GNU-stack,"",@progbits.section	.note.gnu.property,"a".align 8.long	1f - 0f.long	4f - 1f.long	5
0:.string	"GNU"
1:.align 8.long	0xc0000002.long	3f - 2f
2:.long	0x3
3:.align 8
4:

可见普通函数和constexpr函数都可以在汇编函数中展现,但是consteval函数并没有,这也正解释了为什么为什么不能获取函数指针。




END

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

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

相关文章

西南科技大学电路分析基础实验A1(元件伏安特性测试 )

目录 一、实验目的 二、实验设备 三、预习内容(如:基本原理、电路图、计算值等) 1、测定线性电阻的伏安特性 2、二极管伏安特性测试 3、测定实际电压源的伏安特性 四、实验数据及结果分析(预习写必要实验步骤和表格) 1、测定线性电阻的伏安特性 2、二极管伏安特性测…

Redis未授权访问-CNVD-2019-21763复现

Redis未授权访问-CNVD-2019-21763复现 利用项目: https://github.com/vulhub/redis-rogue-getshell 解压后先进入到 RedisModulesSDK目录里面的exp目录下,make编译一下才会产生exp.so文件,后面再利用这个exp.so文件进行远程代码执行 需要p…

能耗远程在线监测系统在工业节能提高效率

摘要:为保证企业实现节能减排目标,设计和使用远程在线监测系统势在必行。远程在线监测系统是基于传感器与网络技术的优势,在企业区域各个位置针对性安装传感器,对实时数据进行采集、编码传输到远程管理系统。远程管理系统对采集的…

系统设计面试指南之分布式任务调度

1 简介 任务是需要资源(CPU 时间、内存、存储、网络带宽等)在指定时间内完成的一段计算工作。 通过智能地将资源分配给任务以满足任务级和系统级目标的系统称为任务调度程序。 任务调度程序: 及时决定和分配资源给任务的过程称为任务调度。 当我们在 Facebook 发…

【EasyExcel】导出excel并支持自定义设置数据行背景颜色等

需求背景: 根据查询条件将列表数据导出,并筛选出满足某个条件的数据,将满足条件的数据的背景颜色设置成黄色。 (本文例子如:name出现的次数大于等于2,将相关数据背景颜色都设置为黄色) …

MySQL备份与恢复(重点)

MySQL备份与恢复(重点) 一、用户管理与权限管理 ☆ 用户管理 1、创建MySQL用户 注意:MySQL中不能单纯通过用户名来说明用户,必须要加上主机。如jack10.1.1.1 基本语法: mysql> create user 用户名被允许连接的主…

java springboot测试类虚拟MVC环境 匹配返回值与预期内容是否相同 (JSON数据格式) 版

上文java springboot测试类鉴定虚拟MVC请求 返回内容与预期值是否相同我们讲了测试类中 虚拟MVC发送请求 匹配返回内容是否与预期值相同 但是 让我意外的是 既然没人骂我 因为我们实际开发 返回的基本都是json数据 字符串的接口场景是少数的 我们在java文件目录下创建一个 dom…

3分钟使用 WebSocket 搭建属于自己的聊天室(WebSocket 原理、应用解析)

文章目录 WebSocket 的由来WebSocket 是什么WebSocket 优缺点优点缺点 WebSocket 适用场景主流浏览器对 WebSocket 的兼容性WebSocket 通信过程以及原理建立连接具体过程示例Sec-WebSocket-KeySec-WebSocket-Extensions 数据通信数据帧帧头(Frame Header&#xff09…

Spring整合web环境

目录 Javaweb三大组件及环境特点 Spring整合web环境的思路及实现 Spring的web开发组件spring-web MVC框架思想及其设计思路 Javaweb三大组件及环境特点 Spring整合web环境的思路及实现 package com.xfy.listener;import com.xfy.config.SpringConfig; import org.springfra…

具备这四个特征的项目经理,牛逼!

大家好,我是老原。 成为一个业绩第一又能准时下班的工作强人,应该是每个职场人的梦想,但现实往往不那么尽如人意…… 虽然如此,但是不代表我们不能向能做到这样的大佬看齐啊。 工作十余年,见过各种各样的职场人士&a…

高级IO select 多路转接实现思路

文章目录 select 函数fd_set 类型timeval 结构体select 函数的基本使用流程文件描述符就绪条件以select函数为中心实现多路转接的思路select 缺陷 select 函数 int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); selec…

6.1 Windows驱动开发:内核枚举SSDT表基址

SSDT表(System Service Descriptor Table)是Windows操作系统内核中的关键组成部分,负责存储系统服务调用的相关信息。具体而言,SSDT表包含了系统调用的函数地址以及其他与系统服务相关的信息。每个系统调用对应SSDT表中的一个表项…

Android中实现RecyclerView,并对item及其多个子控件的点击事件监听

目录 背景 实现RecyclerView 第一步、 新建item的xml 第二步、在activity的布局中引入 RecyclerView 第三步、新建一个adapter 第四步、在activity中初始化绑定adapter即可 实现item及其多个子组件点击事件监听 第一步、 适配器中创建监听对象 第二步、适配器中绑定监听…

搭建测试平台开发(一):Django基本配置与项目创建

一、安装Django最新版本 1 pip install django二、创建Django项目 首先进入要存放项目的目录,再执行创建项目的命令 1 django-admin startproject testplatform三、Django项目目录详解 1 testplatform 2 ├── testplatform  # 项目的容器 3 │ ├── …

提升技能素养,AMCAP做出合适的决策

近年来,智能配置投资与理财逐渐受到关注并走俏。这是一种简单快捷的智慧化理财方式,通过将个人和家族的闲置资金投入到低风险高流动性的产品中。 国际财富管理投资机构AMCAP集团金融分析师表示:智能配置投资与理财之所以持续走俏&#xff0c…

如何选择共模噪声滤波器

在当前电子产品中,绝大多数的高速信号都使用地差分对结构。 差分结构有一个好处就是可以降低外界对信号的干扰,但是由于设计的原因,在传输结构上还会受到共模噪声的影响。 共模噪声滤波器就可以用于抑制不必要的共模噪声,而不会对…

什么是网络攻击?阿里云服务器可以避免被攻击吗?

网络攻击是指:损害网络系统安全属性的任何类型的进攻动作。进攻行为导致网络系统的机密性、完整性、可控性、真实性、抗抵赖性等受到不同程度的破坏。 网络攻击有很多种,网络上常见的攻击有DDOS攻击、CC攻击、SYN攻击、ARP攻击以及木马、病毒等等,所以再…

算法:Java计算二叉树从根节点到叶子结点的最大路径和

要求从根节点到叶子结点的最大路径和,可以通过递归遍历二叉树来实现。对于二叉树中的每个节点,我们都可以考虑包含该节点的最大路径和。在递归的过程中,我们需要不断更新全局最大路径和。 具体的思路 递归函数设计: 设计一个递归函…

蓝桥杯day02——第三大的数

题目 给你一个非空数组,返回此数组中 第三大的数 。如果不存在,则返回数组中最大的数。 示例 1: 输入:[3, 2, 1] 输出:1 解释:第三大的数是 1 。 示例 2: 输入:[1, 2] 输出&…

02-鸿蒙学习之4.0todoList练习

02-鸿蒙学习之4.0todoList练习 代码 /*** 1:组件必须使用Component装饰* 2.Entry 装饰哪个组件,哪个组件就呈现在页面上* 3.被Entry 装饰的入口组件。build()必须有且仅有一个根 ** 容器 ** 组件* 其他的自定义组件,build() 中…