page 1 of 1
Comments: 5 | Views: 2436
RichardRudek
RichardRudek
So what do you expect for nothin'... :P
I think I've discovered a compiler bug.

Well, I don't know wether this is known or not, but if I could get confirmations with both the VS2005 and VS2008 c++ compilers.

I'm working my way through [the safe bool idiom article], and specifically, i found the error implementing the OperatorNot class:

// operator! version
class Testable {
bool not_ok_;
public:
explicit Testable(bool b=true):not_ok_(!b) {}

bool operator!() const {
return not_ok_;
}
};

Notice the not (!) in the initialiser.

When run it does not initialise the not_ok member to false, when instanitating the class like:
 Testable test;
Here's the disassembly of the constructor:
public:
explicit Testable(bool b=true):ok_(b) {}
004115F0 push ebp
004115F1 mov ebp,esp
004115F3 sub esp,0CCh
004115F9 push ebx
004115FA push esi
004115FB push edi
004115FC push ecx
004115FD lea edi,[ebp-0CCh]
00411603 mov ecx,33h
00411608 mov eax,0CCCCCCCCh
0041160D rep stos dword ptr es:[edi]
0041160F pop ecx
00411610 mov dword ptr [ebp-8],ecx
00411613 mov eax,dword ptr [this]
00411616 mov cl,byte ptr [b]
00411619 mov byte ptr [eax],cl
0041161B mov eax,dword ptr [this]
0041161E pop edi
0041161F pop esi
00411620 pop ebx
00411621 mov esp,ebp
00411623 pop ebp
00411624 ret 4

WTF.

I've checked multiple times, and the original source does have the !.

Yet when I switch to the disassembly view, and single-step into the constructor, it shows it (the bit marked in red) without the !. The bit embolded is the actual native code setting the member.

Am I missing something ?

This is using VS2005sp1 (c1xx.dll version 14.0.50727.762)



Sven Groot
Sven Groot
You can't have everything; after all, where would you put it?
No repro here, on either VS2005 SP1 or VS2008.

Could you post a complete, compilable example that exhibits the problem?
Sven Groot
Sven Groot
You can't have everything; after all, where would you put it?

You are violating the one-definition-rule. You have two classes named Testable with external linkage but with different implementations. To allow class definitions to be placed in headers the linker will not complain if a class violates the one-definition-rule, but if all definitions are not the same the behaviour is undefined.

In this case, the linker has chosen the Testable from OperatorBool.cpp so the one from OperatorNot.cpp is also using that version.

If you wish to have different classes with the same name in files that are linked together, you must give the classes internal linkage. In C++ this is done by placing them in an anonymous namespace:

namespace
{
   class Testable
   {
      // stuff
   };
}

If I make that change your example works correctly.

EDIT: Good to know you figured it out yourself. Smiley

page 1 of 1
Comments: 5 | Views: 2436