Reputation: 11
I have a question when I compile my code with ARMCC. The following is my code(code just for test).
void COptimizerAppUi::DoRealWorksByRef(COptimizerAppUi& aObject)
{
if( NULL == &aObject )
{
RDebug::Printf("This is for testing reference,add:%P", &aObject);
aObject.HandleStatusPaneSizeChange();
}
}
Compiling it for my release version with –asm –interleave, I have the following output. There is only one ASM statement produced. All of the code in the body of the function is missing.
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
And then, I compiled it adding –O0, then I get the following output. Here all of the code expected has their own ASM instructions.
_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
So according to the compare of the two outputs, I know the body of the COptimizerAppUi::DoRealWorksByRef was removed by the compiler. Yes, I know there are –O0, –O1, –O2, –O3 to controls the behavior of optimizing. But I searched so many materials and didn’t get how the compiler optimizes the code. So do you have any rules about the compiler optimization? Any comments/detailed info are welcome.
Thanks in advance.
By the way, in my environment: C:\armcc
ARM C/C++ Compiler, RVCT4.0 [Build 902]
Upvotes: 1
Views: 398
Reputation: 11
Thanks for your answers firstly. Another test I made, code is showing below. The ShowLength function can really output something with optimization enabling. Both G++ and CL output.
#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;
}
Upvotes: 0
Reputation: 16290
The C++ standard dictates that getting a reference to NULL
invokes undefined behavior. So the compiler is leveraging that knowledge to optimize away your if
check entirely--that is, it's illegal to have a reference to NULL
, so your if
statement should never be true in a well-formed program. Or in other words, if you have a reference to NULL
, your code is invalid, so the program is free to go haywire.
Upvotes: 5
Reputation: 87396
Please read the answer to this question:
References are not pointers. References are not allowed to be NULL. Your condition NULL == &aObject
will always evaluate to false. The compiler knows this, so it knows that your function will never do anything. When you turn optimizations on, it uses this knowledge to shorten your function.
Upvotes: 3