一个C/C++结构体初始化有趣的现象
我们知道C语言当中结构可以使用{}进行初始化,例如有结构体定义如下:
typedef struct type_t {
int a;
int b;
int c;
int d;
}type_t;
我们可以使用下面的语句来初始化一个变量:
struct type_t o = { 1, 2, 3, 4 }
但是如果像下面这样来初始化,结果会是什么呢?
type_t o = { 8, o.a, o.b, o.c };
其结果是依赖于编译器的实现,笔者分别在VS2010和GCC下进行了测试,结果如下:
1. vs2010下C和C++的结果都是:
o.a = 8, o.b = 8, o.c = 8, o.d = 8
2. GCC的C编译运行结果:
o.a = 8 o.b = 0, o.c = 0, o.d = 4195296
3. GCC的C++编译运行结果:
o.a = 8, o.b = 8, o.c = 8, o.d = 8
为啥会这样呢?带着疑问,笔者又去看了一下反汇编的代码,VS2010的反汇编代码如下:
type_t o = { 8, o.a, o.b, o.c };
004113A8 mov dword ptr [ebp-18h],8
004113AF mov eax,dword ptr [ebp-18h]
004113B2 mov dword ptr [ebp-14h],eax
004113B5 mov eax,dword ptr [ebp-14h]
004113B8 mov dword ptr [ebp-10h],eax
004113BB mov eax,dword ptr [ebp-10h]
004113BE mov dword ptr [ebp-0Ch],eax
这段代码翻译过来的意思就是:
o.a = 8;
eax = o.a
o.b = eax
eax = o.b
o.c = eax
eax = o.c
o.d = eax
gcc编译的反汇编代码:
=> 0x00000000004004cd <+9>: mov -0x20(%rbp),%ecx
0x00000000004004d0 <+12>: mov -0x1c(%rbp),%edx
0x00000000004004d3 <+15>: mov -0x18(%rbp),%eax
0x00000000004004d6 <+18>: movl $0x8,-0x20(%rbp)
0x00000000004004dd <+25>: mov %ecx,-0x1c(%rbp)
0x00000000004004e0 <+28>: mov %edx,-0x18(%rbp)
0x00000000004004e3 <+31>: mov %eax,-0x14(%rbp)
这段代码可翻译如下:
ecx=o.a
edx=o.b
eax=o.c
o.a=8
o.b=ecx
o.c=edx
o.d=eax
g++编译的反汇编代码:
=> 0x00000000004005ad <+9>: movq $0x0,-0x20(%rbp)
0x00000000004005b5 <+17>: movq $0x0,-0x18(%rbp)
0x00000000004005bd <+25>: movl $0x8,-0x20(%rbp)
0x00000000004005c4 <+32>: mov -0x20(%rbp),%eax
0x00000000004005c7 <+35>: mov %eax,-0x1c(%rbp)
0x00000000004005ca <+38>: mov -0x1c(%rbp),%eax
0x00000000004005cd <+41>: mov %eax,-0x18(%rbp)
0x00000000004005d0 <+44>: mov -0x18(%rbp),%eax
0x00000000004005d3 <+47>: mov %eax,-0x14(%rbp)
这段代码翻译如下:
将o变量清零
o.a = 8;
eax = o.a
o.b = eax
eax = o.b
o.c = eax
eax = o.c
o.d = eax
现在该完全清楚了,g++和vs2010生成的汇编指令基本一致,都是先将前一个成员初始化后再进行取值。而gcc则是先将o的成员变量值全部保存的寄存器中,然后逐一对o变量进行初始化。
但是所不明白的是为何gcc要这样生成指令?
一个C/C++结构体初始化有趣的现象的更多相关文章
- Linux C中结构体初始化
在阅读GNU/Linux内核代码时,我们会遇到一种特殊的结构初始化方式.该方式是某些C教材(如谭二版.K&R二版)中没有介绍过的.这种方式称为指定初始化(designated in ...
- struct--------构造函数对结构体初始化的影响
struct--------构造函数对结构体初始化的影响. 没有构造函数时使用如下: struct ClassBook{ int number; int age; }; int main() { ...
- PAT A1075 PAT Judge (25 分)——结构体初始化,排序
The ranklist of PAT is generated from the status list, which shows the scores of the submissions. Th ...
- Linux C 结构体初始化三种形式
最近看linux代码时发现了结构体 struct 一种新的初始化方式,各方查找对比后总结如下: 1. 顺序初始化教科书上讲C语言结构体初始化是按照顺序方式来讲的,没有涉及到乱序的方式.顺序初始化str ...
- Linux下C结构体初始化[总结]
1.前言 今天在公司看一同事写的代码,代码中用到了struct,初始化一个struct用的是乱序格式,如下代码所示: typedef struct _data_t { int a; int b; }d ...
- Linux下C结构体初始化
1.前言 今天在公司看一同事写的代码,代码中用到了struct,初始化一个struct用的是乱序格式,如下代码所示: typedef struct _data_t { int a; int b; }d ...
- C语言结构体初始化方法
早上苏凯童鞋问我这个问题来着,写在这里. 我了解到的C中结构体初始化的方法大概有三种. 如这里我定义了一个结构体: typedef struct node { int x, y; }Node; 第一种 ...
- golang | Go语言入门教程——结构体初始化与继承
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是golang专题第10篇文章,我们继续来看golang当中的面向对象部分. 在上一篇文章当中我们一起学习了怎么创建一个结构体,以及怎么 ...
- 【2016-08-18】转载:总结C++中几种结构体初始化的方法
作者:Ac_Von 博客地址:http://www.cnblogs.com/vongang/ 文章地址:http://www.cnblogs.com/vongang/archive/2011/07/3 ...
随机推荐
- c++ 17介绍
作者:hearts zh链接:https://www.zhihu.com/question/32222337/answer/55238928来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商 ...
- C语言运算符的优先级
熟悉C语言的同学都知道,C语言众多的运算符及繁琐难记的优先级总是搞得我们这些C初学者头大.那么本文就 对C语言中所有的运算符进行汇总,并对其优先级进行一定的介绍. 这里虽然对所有C运算符的优先级进行了 ...
- hdu 2571 命运(dp)
Problem Description 穿过幽谷意味着离大魔王lemon已经无限接近了! 可谁能想到,yifenfei在斩杀了一些虾兵蟹将后,却再次面临命运大迷宫的考验,这是魔王lemon设下的又一个 ...
- Appium for Windows环境搭建
服务环境: 1.安装Nodejs 下载nodejs安装包(http://nodejs.org/download/)安装 测试安装是否成功:运行cmd,输入node -v 2.安装android的SKD ...
- iOS 监听 出发 Home键 NSNotificationCenter UIApplicationWillResignActiveNotification
第一步: 创建2个NSNotificationCenter监听 [[NSNotificationCenter defaultCenter] addObserver:self selector:@sel ...
- CSS Transform让百分比宽高布局元素水平垂直居中
很早以前了解过当元素是固定宽度和高度的时候,水平垂直高居中的方法可以设置margin的负值来使其居中,这个负值是元素的宽和高的一半,比如宽高是100px,那么就用margin-left:-50px;m ...
- 【单点更新,区间查询,线段树】【HDU1166】【敌兵布阵】
线段树要捡回来学了 才知道以前抄的模板就是杭电传奇学长写的,写起来更有激情了: 一点注意: 单点更新完后记得pushup(),向上更新信息 以下是对线段树的理解 线段树的节点代表一段线段,节点编号没有 ...
- 初识动画animation
工作半年了,基本没怎么用到动画,现在对已学到的动画做一个总结(真的非常非常基础啊啊啊),准备之后再慢慢研究一下动画(有好的教程可以推荐给我咩~~). animation animation:mymov ...
- C# @字符用法
1.用 @ 符号加在字符串前面表示其中的转义字符“不”被处理. 如果我们写一个文件的路径,例如"D:/文本文件"路径下的text.txt文件,不加@符号的话写法如下: string ...
- PHP上传图片至阿里云
<?php header("Content-type: text/html; charset=utf-8"); header('Access-Control-Allow-Or ...