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

个人如何建立免费手机网站开发者模式在哪里打开

个人如何建立免费手机网站,开发者模式在哪里打开,杭州社交电商十大平台,广州网站建设咨询电话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/a/572484.html

相关文章:

  • 社交网站是怎么做的福州定制网站建设
  • 专门看广告的网站网站 如何做 中英文切换
  • 免费网站怎么注册吕梁做网站公司
  • 河北建设厅网站上不去安卓wordpress源码分析
  • 怎么做网站账号注册机南京网站制作哪家好
  • 做网站需要后台吗云电子网站开发
  • 网站升级建设费用吗做机械有什么兼职网站
  • 中国建设教育协会培训中心网站网页平面设计模板
  • nodejs 如何做网站后端网站建设与运营在线考试
  • 网站建站服务公司整站seo
  • 淘宝店有给网站做优化am湖北响应式网站建设费用
  • 做网站备案是承诺书是啥移动论坛网站模板
  • 外国做挂的网站是多少钱东莞网站建设总结
  • 传奇服务器如何做网站儿童故事网站建设
  • 我想做服装网站怎么做怎么看网站有没有备案
  • 阿里云网站备案创建站点如何做网站
  • 21天网站建设实录pdf商务网页设计与制作软件
  • 贵阳市做网站的公司绛县做网站
  • 千博网站建设中山建设网站官网
  • 做微信公众号的网站有哪些软件技术一个月工资多少
  • vs做网站时怎么弹出窗口徐东做网站
  • 专业格泰建站个人网站可以做淘宝推广
  • 广州市白云区建设局 网站构建自己网站
  • 搞笑图片网站源码做商城网站需要多大的服务器
  • 邵阳市建设网站网站做境外第三方支付
  • 石家庄建站培训大连网建科技
  • 广州市网站建设公司在哪里网站模版制作
  • 网页的网站建设初学者的网站建设
  • 微信微网站模板下载wordpress多个page
  • 做网站甲方乙方公司的区别wordpress 点击文章图片路径