当我用ARMCC编译我的代码时,我有一个问题。以下是我的代码(代码仅用于测试)。
void COptimizerAppUi::DoRealWorksByRef(COptimizerAppUi& aObject)
{
if( NULL == &aObject )
{
RDebug::Printf("This is for testing reference,add:%P", &aObject);
aObject.HandleStatusPaneSizeChange();
}
}使用-asm-interleave为我的发布版本编译它时,我得到了以下输出。只生成了一条ASM语句。函数体中的所有代码都丢失。
COptimizerAppUi::DoRealWorksByRef(COptimizerAppUi&)
;;;216
;;;217 void COptimizerAppUi::DoRealWorksByRef(COptimizerAppUi& aObject)
000254 4770 BX lr
;;;218 {
;;;219 if( NULL == &aObject )
;;;220 {
;;;221 RDebug::Printf("This is for testing reference,add:%P", &aObject);
;;;222 aObject.HandleStatusPaneSizeChange();
;;;223 }
;;;224 }
;;;225然后,我添加-O0对其进行编译,然后得到以下输出。这里,所有预期的代码都有自己的ASM指令。
_ZN15COptimizerAppUi16DoRealWorksByRefERS_ PROC ;
COptimizerAppUi::DoRealWorksByRef(COptimizerAppUi&)
;;;216
;;;217 void COptimizerAppUi::DoRealWorksByRef(COptimizerAppUi& aObject)
000328 b570 PUSH {r4-r6,lr}
;;;218 {
00032a 0005 MOVS r5,r0
00032c 000c MOVS r4,r1
;;;219 if( NULL == &aObject )
00032e 2c00 CMP r4,#0
000330 d108 BNE |L1.836|
;;;220 {
;;;221 RDebug::Printf("This is for testing reference,add:%P", &aObject);
000332 0021 MOVS r1,r4
000334 a01a ADR r0,|L1.928|
000336 f7fffffe BL _ZN6RDebug6PrintfEPKcz ; RDebug::Printf(const char*, ...)
;;;222 aObject.HandleStatusPaneSizeChange();
00033a 6820 LDR r0,[r4,#0]
00033c 3080 ADDS r0,r0,#0x80
00033e 6a81 LDR r1,[r0,#0x28]
000340 0020 MOVS r0,r4
000342 4788 BLX r1
|L1.836|
;;;223 }
;;;224 }
000344 bd70 POP {r4-r6,pc}
;;;225
ENDP因此,根据两个输出的比较,我知道COptimizerAppUi::DoRealWorksByRef的主体被编译器删除了。是的,我知道有-O0,-O1,-O2,-O3来控制优化的行为。但是我搜索了这么多资料,都不知道编译器是如何优化代码的。那么你有什么关于编译器优化的规则吗?欢迎任何意见/详细信息。
提前谢谢。
顺便说一下,在我的环境中: C:\armcc
ARM C/C++编译器,RVCT4.0内部版本902
发布于 2012-02-03 15:53:17
C++标准规定,获取对NULL的引用将调用未定义的行为。因此,编译器正在利用这些知识来完全优化您的if检查--也就是说,引用NULL是非法的,因此您的if语句在格式良好的程序中永远不应该为真。或者换句话说,如果您引用了NULL,那么您的代码就是无效的,因此程序就会陷入混乱。
发布于 2012-02-03 15:49:16
请阅读以下问题的答案:
引用不是指针。引用不允许为空。您的条件NULL == &aObject将始终计算为false。编译器知道这一点,所以它知道你的函数永远不会做任何事情。当您打开优化时,它会使用这些知识来缩短您的函数。
发布于 2012-02-06 10:27:57
首先感谢你的回答。我做的另一个测试,代码如下所示。在启用优化的情况下,ShowLength函数确实可以输出一些内容。G++和CL输出。
#include <iostream>
#include <vector>
using namespace std;
void ShowLength( vector<int>& vec )
{
if( 0 == &vec )
{
cout << "vec::lenght = 0" << endl;
}
}
int main(int argc, char* arv[] )
{
vector<int> *p = 0;
vector<int> &ref = *p;
ShowLength( ref );
return 0;
}https://stackoverflow.com/questions/9125129
复制相似问题