一个关于不同编译器对operator++和operator+=的处理方式的问题

首先,上代码:

#include <stdio.h>
#include <iostream>
using namespace std;
int main()
{
	int a = 5;
	printf("a++ = %d\n", a++);

	a = 5;
	printf("++a = %d\n", ++a);

	a = 5;
	printf("a += a++  =%d\n", a += a++);
	a = 5;
	printf("a += (a++)  =%d\n", a = a + (a++));

	a = 5;
	printf("a += ++a  =%d\n", a += ++a);
	a = 5;
	printf("a += (++a)  =%d\n", a += (++a));

	a = 5;
	printf("++a += a++ =%d\n", ++a += a++);
	a = 5;
	printf("(++a) += (a++) =%d\n", (++a) += (a++));

	return 1;
}

不知道各位看官看到这儿有什么想法,你认为它们的输出值应该是什么?

不卖关子了,直接给出VS2013下的运行结果和g++ 4.8.2编译出的运行结果:

如此截然不同的结果,那么我们看一下汇编代码(只截取了【printf("a += a++  =%d\n", a += a++);】部分的汇编作为示例,具体的大家可以自己看一下):

/* vs2013 */
    13: 	printf("a += a++  =%d\n", a += a++);
011ECAC7  mov         eax,dword ptr [a]
011ECACA  add         eax,dword ptr [a]
011ECACD  mov         dword ptr [a],eax
011ECAD0  mov         ecx,dword ptr [a]
011ECAD3  mov         dword ptr [ebp-0D0h],ecx
011ECAD9  mov         edx,dword ptr [a]
011ECADC  add         edx,1
011ECADF  mov         dword ptr [a],edx
011ECAE2  mov         esi,esp
011ECAE4  mov         eax,dword ptr [ebp-0D0h]
011ECAEA  push        eax
011ECAEB  push        11F832Ch
011ECAF0  call        dword ptr ds:[11FC1E4h]
011ECAF6  add         esp,8
011ECAF9  cmp         esi,esp
011ECAFB  call        __RTC_CheckEsp (011E1631h)  
/* g++ 4.8.2 */
13		printf("a += a++  =%d\n", a += a++);
   0x08048602 <+85>:	mov    0x1c(%esp),%eax
   0x08048606 <+89>:	lea    0x1(%eax),%edx
   0x08048609 <+92>:	mov    %edx,0x1c(%esp)
   0x0804860d <+96>:	add    %eax,0x1c(%esp)
   0x08048611 <+100>:	mov    0x1c(%esp),%eax
   0x08048615 <+104>:	mov    %eax,0x4(%esp)
   0x08048619 <+108>:	movl   $0x8048814,(%esp)
   0x08048620 <+115>:	call   0x80484a0 <[email protected]>

我书读得少,汇编更是自学成才,希望大家能帮忙解释一下是神马情况~~~,小弟多谢了!

【注】上述代码运行平台均为32位操作系统,其中vs2013运行于Windows 8.1 企业版,g++运行于ubuntu14.04 (3.13.0-41-generic)

时间: 2024-10-18 04:29:50

一个关于不同编译器对operator++和operator+=的处理方式的问题的相关文章

C++ new/new operator、operator new、placement new初识

简要释义 1.operator new是内存分配函数(同malloc),C++在全局作用域(global scope)内提供了3份默认的operator new实现,并且用户可以重载operator new. 1 void* operator new(std::size_t) throw(std::bad_alloc);//normal new 2 void* operator new(std::size_t,const std::nothrow_t&) throw();//nothrow ne

C++ new operator, delete operator, operator new, operator delete, new placement

http://www.younfor.com/cpp-new-placement-new-operator-new.html http://www.cnblogs.com/luxiaoxun/archive/2012/08/10/2631812.html http://kelvinh.github.io/blog/2014/04/19/research-on-operator-new-and-delete/ new operator 就是C++中定义的关键字new,调用new而触发的行为,del

C++内存管理(new operator/operator new/operator delete/placement new)

new operator 我们平时使用的new是new操作符(new operator),就像sizeof一样是语言内置的,不能改变它的含义,功能也是一样的 比如: string *ps = new string("Memory Management"); 相当于 void *memory = operator new(sizeof(string)); // 得到未经处理的内存,为String对象 call string::string("Memory Management&

C++中的new/delete与operator new/operator delete

new operator/delete operator就是new和delete操作符,而operator new/operator delete是函数. new operator(1)调用operator new分配足够的空间,并调用相关对象的构造函数(2)不可以被重载 operator new(1)只分配所要求的空间,不调用相关对象的构造函数.当无法满足所要求分配的空间时,则        ->如果有new_handler,则调用new_handler,否则        ->如果没要求不

调用operator+=来定义operator+比其他方法更有效?

如题,下面给出operator+=和operator+的实现 1 Sales_data& 2 Sales_data::operator+=(const Sales_data &rhs) 3 { 4 units_sold += rhs.units_sold; 5 revenue += rhs.revenue; 6 return *this; 7 } 8 9 Sales_data 10 operator+(const Sales_data &lhs, const Sales_data

第一个C语言编译器是怎样编写的?

首先向C语言之父Dennis MacAlistair Ritchie致敬! 当今几乎所有的实用的编译器/解释器(以下统称编译器)都是用C语言编写的,有一些语言比如Clojure,Jython等是基于JVM或者说是用Java实现的,IronPython等是基于.NET实现的,但是Java和C#等本身也要依靠C/C++来实现,等于是间接调用了调用了C.所以衡量某种高级语言的可移植性其实就是在讨论ANSI/ISO C的移植性. C语言是很低级的语言,很多方面都近似于汇编语言,在<Intel32位汇编语

你知道第一个 C 语言编译器是如何编写的吗?

C语言是很低级的语言,很多方面都近似于汇编语言,在<Intel 32位汇编语言程序设计>一书中,甚至介绍了手工把简单的C语言翻译成汇编的方法.对于编译器这种系统软件,用C语言来编写是很自然不过的,即使是像Python这样的高级语言依然在底层依赖于C语言(举Python的例子是因为Intel的黑客正在尝试让Python不需要操作系统就能运行--实际上是免去了BIOS上的一次性C代码).现在的学生,学过编译原理后,只要有点编程能力的都可以实现一个功能简单的类C语言编译器. 可是问题来了,不知道你有

operator++() 和operator++(int)

#include <iostream> using namespace std; class A{ public: int a; public: A& operator++(){ cout<<"A& operator++()"<<endl; a=a+1; return *this; } A operator++(int){ cout<<"A operator++(int)"<<endl; A

C++中的::operator new, ::operator delete

一般在使用new  和 delete的时候,做了两件事情,一是空间的配置( new 是分配,delete是回收),而是调用对象的析构函数 但是也有办法将这两个过程分开 那就是显式的调用::operator new, ::operator delete,它们只进行空间配置,并不调用对象的析构函数 具体的可以参看下面这个例子: // operator new[] example #include <iostream> // std::cout #include <new> // ::o

【转】写一个C语言编译器 : BabyC

[转载]此文是转载,方便以后读与学习. 原文链接:http://blog.jobbole.com/77305/ 动手编写一个编译器,学习一下较为底层的编程方式,是一种学习计算机到底是如何工作的非常有效方法. 编译器通常被看作是十分复杂的工程.事实上,编写一个产品级的编译器也确实是一个庞大的任务.但是写一个小巧可用的编译器却不是这么困难. 秘诀就是首先去找到一个最小的可用工程,然后把你想要的特性添加进去.这个方法也是Abdulaziz Ghuloum在他那篇著名的论文“一种构造编译器的捷径”里所提