当前位置: 首页 > wzjs >正文

做网站和做系统的区别网址

做网站和做系统的区别,网址,网站收录需要多久,安徽省合肥市庐江县疫情最新消息author: hjjdebug date: 2025年 04月 23日 星期三 13:40:21 CST description: c中的enum变量 和 constexpr说明符 文章目录 1.Q:enum 类型变量可以有,--操作吗?1.1补充: c/c中enum的另一个细微差别. 2.Q: constexpr 修饰的函数,要求传入的参数必需是常量吗&#xff…

author: hjjdebug
date: 2025年 04月 23日 星期三 13:40:21 CST
description: c++中的enum变量 和 constexpr说明符


文章目录

    • 1.Q:enum 类型变量可以有++,--操作吗?
      • 1.1补充: c/c++中enum的另一个细微差别.
    • 2.Q: constexpr 修饰的函数,要求传入的参数必需是常量吗?
    • 3. Q constexpr 编译期求值真正的意思是什么?
      • 3.1 debug 版本, constexpr 修饰无效
      • 3.2 release 版本, constexpr 函数被优化掉了
    • 4. constexpr 中碰到了一个左值引用绑定问题
    • 5 x86-64 linux系统上函数调用传参约定

本来应该分2篇博客写的,放一起吧,也有相关性,都是c++的.

1.Q:enum 类型变量可以有++,–操作吗?

A: c支持,c++不支持.
c++中的enum 类型变量和c中的enum变量基本含义相同,但又略有区别.
试验代码:

$ cat main.c
#include <stdio.h>
typedef enum _ABC { E0,E1,E2}ABC;
int main() 
{ABC a=E0;a++;return 0;
}

c语言是支持enum类型变量++或–这种操作的,因为它天然认为enum类型就是整形
将main.c改名为main.cpp文件,则编译不通过
给出的编译错误为:

error: no ‘operator++(int)’ declared for postfix ‘++’ [-fpermissive]

没有后++的操作运算符说明, operator++(int), 不允许的操作.
就是说c++编译器认为enum 类型是一种新的类型,并不是整型,虽然它的内部实现是把它当整形来实现的.
那如何解除这种限制呢?
如下:多加一行代码, 重载 ABC operator++(int)类型的函数. 就可以对ABC 型变量执行后++操作

$cat main.cpp
#include <stdio.h>
typedef enum _ABC { E0,E1,E2}ABC;
constexpr ABC operator++(ABC d,int) {return ABC((int)d+1);}
int main() 
{ABC a=E0;a++;return 0;
}

1.1补充: c/c++中enum的另一个细微差别.

c++中可以不用typedef 重定义类型,而直接使用enum 就可以了.如下:
enum ABC {E0,E1,E2}, 其它代码不动.
而c语言不行,
如果去掉typedef 重定义,你需要在声明变量时加上enum声明,如下:
enum ABC a=E0
否则会有编译错误,如下:

error: unknown type name ‘ABC’; use ‘enum’ keyword to refer to the type
| ABC a=E0;
| ^~~

2.Q: constexpr 修饰的函数,要求传入的参数必需是常量吗?

答: 不是
这个constexpr修饰的函数,网上说是可以编译期求值,要求传入常量值.
我看说法不完全正确,这里我传入a就是内存变量,不是常量
我还可以写如下代码:
for(int i=0;i<2;i++)
{
a++; // 这个a 是不断变化的.
printf(“a is %d\n”, (int)a);
}

3. Q constexpr 编译期求值真正的意思是什么?

A: constexpr函数并不会进入执行文件中,执行文件中没有这个函数.
正确的理解constexpr的编译期求值, 是它在运行时不求值,
就是说它已经做到了运行时, 不进入你定义的constexpr函数,
例如对该例,它的a++就直接变成了整数的a++
并不是说一定要传入常量值.

3.1 debug 版本, constexpr 修饰无效

这只是我的一种猜测,后面我会证明,
如果编译成debug版调试程序,它总是会跟入函数的, 这不是constexpr 的初衷
对debug版本,加不加constexpr 效果是一样的.

3.2 release 版本, constexpr 函数被优化掉了

那么对release 版是否真的把constexpr函数给优化掉了呢?那要反汇编代码了.
开干吧! 源代码如下:

#include <stdio.h>
typedef enum _ABC { E0,E1,E2}ABC;
constexpr ABC& operator++(ABC& d,int) {return d=ABC((int)d+1);}
int main()
{ABC a=E0;for(int i=0;i<5;i++){a++;}return 0;
}

release 版反编译代码
我惊讶的发现, 我的main函数被它优化成空函数了
如下:
0000000000001040 :
1040: f3 0f 1e fa endbr64
1044: 31 c0 xor %eax,%eax
1046: c3 retq
1047: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1)

什么for循环, enum 变量,统统都是空.
哇! 这么利害,把代码全优化掉了,它认为我这些代码都是没用的东西.
是的,如果把main也当成一个一般的子函数看,它除了占用点cpu资源,对外界就没有什么影响.

我们加上printf 代码,让代码变得有用起来. 不能让它全优化了.

#include <stdio.h>
typedef enum _ABC { E0,E1,E2}ABC;
constexpr ABC& operator++(ABC& d,int) {return d=ABC((int)d+1);}
int main()
{ABC a=E0;for(int i=0;i<5;i++){a++;printf("a is %d\n",(int)a);}return 0;
}

release 版反编译代码

0000000000001060 <main>:1060:	f3 0f 1e fa          	endbr64 1064:	55                   	push   %rbp  //rbp 如栈,框架1065:	48 8d 2d 98 0f 00 00 	lea    0xf98(%rip),%rbp # 2004 <_IO_stdin_used+0x4>106c:	53                   	push   %rbx  //rbx 入栈,它会做为a变量106d:	bb 01 00 00 00       	mov    $0x1,%ebx //ebx 就是a变量,初始值给了1,因为它知道第一次打印值是1,利害!1072:	48 83 ec 08          	sub    $0x8,%rsp //调整堆栈,为局部变量准备空间1076:	89 da                	mov    %ebx,%edx // a变量送给edx, printf 的第二个参数1078:	48 89 ee             	mov    %rbp,%rsi // rsi, printf 的第一个参数,字符串地址107b:	bf 01 00 00 00       	mov    $0x1,%edi // rdi=1,向stdout输出,因为它调用的是__printf_chk1080:	31 c0                	xor    %eax,%eax // 表示传递的浮点数个数是0个1082:	e8 c9 ff ff ff       	callq  1050 <__printf_chk@plt>1087:	83 c3 01             	add    $0x1,%ebx        // ebx 为a变量//它算出了a变量和i变量的对应关系,所以优化掉i变量,让a变量与6比,果然很智能!108a:	83 fb 06             	cmp    $0x6,%ebx      108d:	75 e7                	jne    1076 <main+0x16> //循环到1076108f:	48 83 c4 08          	add    $0x8,%rsp   //局部空间栈恢复1093:	31 c0                	xor    %eax,%eax  //返回值1095:	5b                   	pop    %rbx   //恢复rbx1096:	5d                   	pop    %rbp //恢复rbp1097:	c3                   	retq   //函数返回 1098:	0f 1f 84 00 00 00 00 	nopl   0x0(%rax,%rax,1)109f:	00 

完美验证了我的设想!constexpr 函数优化后不会出现在运行期,但它也不会要求参数必需是常量,变量也行,只要能被它替代就行.

4. constexpr 中碰到了一个左值引用绑定问题

代码:
constexpr ABC& operator++(ABC& d,int) {return ABC((int)d+1);}
error: cannot bind non-const lvalue reference of type ‘ABC&’ {aka ‘_ABC&’} to an rvalue of type ‘ABC’ {aka ‘_ABC’}
错误是说: 不能够让非-const 的左值ABC& 类型与右值 ABC类型相绑定.
就是说要返回引用,而不要返回值

修改方法.
返回一个值的引用. 一个变量的别名叫引用,引用在函数间传递的是地址,该函数实际的意义就是修改自身.
所以函数内把值再变成引用.如下:添加d=内容,把值送给引用.
constexpr ABC& operator++(ABC& d,int) {return d=ABC((int)d+1);}

5 x86-64 linux系统上函数调用传参约定

采用System V AMD64 调用约定.
前六个整型参数(包括指针)通过寄存器传递
顺序RDI、RSI、RDX、RCX R8 R9 ,超过6个多余的用堆栈传,从右向左顺序压入堆栈.
例: test(0,1,2,3,4,5,6) 7个参数
31 ff xor %edi,%edi
be 01 00 00 00 mov $0x1,%esi
ba 02 00 00 00 mov $0x2,%edx
b9 03 00 00 00 mov $0x3,%ecx
41 b8 04 00 00 00 mov $0x4,%r8d
41 b9 05 00 00 00 mov $0x5,%r9d
6a 06 pushq $0x6
//test 函数c++中变成了_Z4Testiiiiiii,名称带参数类型,_Z是gcc的函数标志,4是名称长度,7个i是7个整形参数
e8 04 01 00 00 callq 1190 <_Z4Testiiiiiii>

http://www.dtcms.com/wzjs/187650.html

相关文章:

  • 微商如何做网站引流百度企业认证怎么认证
  • 佛山网站设计制作公司郑州今日头条
  • 如何搭建情侣网站推广普通话内容50字
  • 网页制作网站开发室内设计培训哪个机构比较好
  • 成都谁做捕鱼网站螺蛳粉营销策划方案
  • 中企动力网站建设网站模板
  • 做爰网站有哪些品牌策划方案模板
  • 厦门微信网站建设企业官网定制设计
  • ftp上传网站后怎么弄化妆品软文推广范文
  • 做铝锭的网站网页制作接单
  • 张家港做网站广告公司链接式友谊
  • 北海网站设计百度知道一下
  • 可以做动画的网站都有哪些软件英语培训机构
  • 如何评价伊利集团网站建设教育培训机构排名前十
  • 网站建设杭州哪家便宜网站优化要多少钱
  • 做网站是什么专业电子商务营销的概念
  • 乳源建设局网站培训机构排名全国十大教育机构排名
  • 公众号网站怎么做的一篇好的营销软文
  • 网站建设简介网络广告投放平台
  • 找个做游戏的视频网站百度网站关键词优化
  • 建设网站你认为需要注意做关键词推广
  • 做外贸哪里网站比较好互联网营销方式有哪些
  • 树荫营销网站宁波免费seo排名优化
  • 南昌做网站装修的企业查询关键词排名工具
  • 号码百事通给做网站吗seo优化自学
  • 洛阳有做网站开发的吗网上写文章用什么软件
  • 电子商务网站建设的风险分析哪里有免费的网站推广软件
  • 现在注册公司流程和费用武汉seo搜索优化
  • 四川做网站设计哪家好今日头条新闻最新事件
  • 油气集输毕业设计代做网站爱站查询