一个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 ...
随机推荐
- Windows查看电脑上安装的.Net Framework版本的五种方法(转)
1.查看安装文件判断Framwork版本号 打开资源管理器,比如我的电脑,再地址栏输入%systemroot%\Microsoft.NET\Framework后单击“转到”或者按回车. 在新文件夹中查 ...
- [置顶] Ajax核心--XMLHttpRequest对象
XMLHttpRequest 对象是AJAX功能的核心,学习XMLHttpRequest对象就先从创建XMLHttpRequest 对象开始,了解在不同的浏览器中创建XMLHttpRequest 对象 ...
- IOS开发(objective-c)~开篇有理
自从6月份买了iphone5之后,心里都是觉得不学点IOS开发,始终觉得有点浪费,而且咱还学习C,C++,java,C#,有了这些基础,再不学这个Objective-c确实有点可惜了,所以,说干就干, ...
- OC基础3:一些基本概念
"OC基础"这个分类的文章是我在自学Stephen G.Kochan的<Objective-C程序设计第6版>过程中的笔记. 1.关于NSLog函数中的“%2i”: ( ...
- Newton‘ method 的优缺点
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzE1Mjg5NQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...
- 【递推+矩阵快速幂】【HDU2604】【Queuing】
Queuing Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...
- Jquery揭秘系列:谈谈bind,one,live,delegate,on事件及实现
在Jquery里面,我们用的最多的就是事件绑定了,事件绑定有多个函数.例如:bind,one,live,delegate,on等等. on() jQuery事件绑定.on()简要概述及应用 看源码发现 ...
- jQuery渐隐渐出的文字提示
<html> <head> <title>jquery渐隐渐出的文字提示</title> <style type="text/css&q ...
- Linux下配置VNC
1.确认是否安装vnc服务端 : rpm -q tigervnc-server 默认是没有安装的,需要在Linux系统文件Packages文件夹找到vnc安装包(里面有两个分别是客户端与服务端)tig ...
- Linux下进程的文件访问权限
本文转自 http://blog.csdn.net/chosen0ne/article/details/10581883 对进程校验文件访问权限包括两个部分,一是确定进程的角色(属于哪个用户或者组), ...