我们知道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++结构体初始化有趣的现象的更多相关文章

  1. Linux C中结构体初始化

          在阅读GNU/Linux内核代码时,我们会遇到一种特殊的结构初始化方式.该方式是某些C教材(如谭二版.K&R二版)中没有介绍过的.这种方式称为指定初始化(designated in ...

  2. struct--------构造函数对结构体初始化的影响

    struct--------构造函数对结构体初始化的影响. 没有构造函数时使用如下: struct ClassBook{  int number;  int age; }; int main() { ...

  3. PAT A1075 PAT Judge (25 分)——结构体初始化,排序

    The ranklist of PAT is generated from the status list, which shows the scores of the submissions. Th ...

  4. Linux C 结构体初始化三种形式

    最近看linux代码时发现了结构体 struct 一种新的初始化方式,各方查找对比后总结如下: 1. 顺序初始化教科书上讲C语言结构体初始化是按照顺序方式来讲的,没有涉及到乱序的方式.顺序初始化str ...

  5. Linux下C结构体初始化[总结]

    1.前言 今天在公司看一同事写的代码,代码中用到了struct,初始化一个struct用的是乱序格式,如下代码所示: typedef struct _data_t { int a; int b; }d ...

  6. Linux下C结构体初始化

    1.前言 今天在公司看一同事写的代码,代码中用到了struct,初始化一个struct用的是乱序格式,如下代码所示: typedef struct _data_t { int a; int b; }d ...

  7. C语言结构体初始化方法

    早上苏凯童鞋问我这个问题来着,写在这里. 我了解到的C中结构体初始化的方法大概有三种. 如这里我定义了一个结构体: typedef struct node { int x, y; }Node; 第一种 ...

  8. golang | Go语言入门教程——结构体初始化与继承

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是golang专题第10篇文章,我们继续来看golang当中的面向对象部分. 在上一篇文章当中我们一起学习了怎么创建一个结构体,以及怎么 ...

  9. 【2016-08-18】转载:总结C++中几种结构体初始化的方法

    作者:Ac_Von 博客地址:http://www.cnblogs.com/vongang/ 文章地址:http://www.cnblogs.com/vongang/archive/2011/07/3 ...

随机推荐

  1. Google map v3 using simple tool file google.map.util.js v 1.1

    /** * GOOGLE地图开发使用工具 * @author BOONYACHENGDU@GMAIL.COM * @date 2013-08-23 * @notice 地图容器的z-index不能小于 ...

  2. centos curl web站点监控实践

    1,监控给定web站点的状态--站点请求返回代码,下载整个web站点页面文本到-o 指定的文本 curl -o /dev/null -s-silent -w--wirte-out "%{ht ...

  3. hdu 5506 GT and set(dfs爆搜)

    Problem Description You are given N sets.The i−th set has Ai numbers.You should divide the sets into ...

  4. Lining Up(在一条直线上的最大点数目,暴力)

    Lining Up Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total ...

  5. 【线段树】【3-21个人赛】【同样的problemB】

    同一道题  http://blog.csdn.net/zy691357966/article/details/44680121 区间查询最大值 用线段树 比单调队列慢 #include <cst ...

  6. HTML网页制作:[12]使用框架结构之frameset

    首先,我希望在你的目录下,有4个网页,各自显示不同的内容. 如图所示: 1.html显示“火影忍者” 2.html显示“英雄联盟” 3.html显示“嵌入式开发.网页开发.安卓开发” 4.html显示 ...

  7. 用友U8客户端连接不上服务器全攻略

    用友U8客户端连接不上服务器全攻略 http://www.enet.com.cn2009年09月23日09:26 来自论坛 [导读]:如果网络不通,就让用户查找网络原因 检查步骤: 1.网络是否通? ...

  8. C# for循环 迭代法 穷举法应用

    迭代 //兔子生兔子 class Class5    { static void Main(string[] args) { int tu1 = 1, tu2 = 1; //tu1是倒数第一个月的兔子 ...

  9. [Linked List]Reverse Linked List,Reverse Linked List II

    一.Reverse Linked List  (M) Reverse Linked List II (M) Binary Tree Upside Down (E) Palindrome Linked ...

  10. zoj1183 Scheduling Lectures

    这道题题意不想说了,跑了640ms,感觉水过去了,应该能通过单调队列优化,很长时间没碰已经不知道怎么写了,就说说现在的写法吧. 状态定义很关键:dp[i][j]把前j个topic放在前i堂课. 因为这 ...