Re: Optimizer bug (VC6 and VC7.1)?
From: Doug Harrison [MVP] (dsh_at_mvps.org)
Date: 11/18/04
- Next message: Tomas Restrepo \(MVP\): "Re: C3830 error appeared for no apparent reason?"
- Previous message: Brian Ross: "Optimizer bug (VC6 and VC7.1)?"
- In reply to: Brian Ross: "Optimizer bug (VC6 and VC7.1)?"
- Next in thread: Brian Ross: "Re: Optimizer bug (VC6 and VC7.1)?"
- Reply: Brian Ross: "Re: Optimizer bug (VC6 and VC7.1)?"
- Messages sorted by: [ date ] [ thread ]
Date: Wed, 17 Nov 2004 19:23:49 -0600
Brian Ross wrote:
>Hi,
>
>Would it be fair to say the following is an optimizer bug?
I think your code is undefined, so I'd hesitate to call it an optimizer bug.
See below.
>--- Test.cpp ---
>
>#include <cstdio>
>
>using std::printf;
>
>typedef int* IntPointer;
>
>class CTestClass
>{
> public:
>
> CTestClass(const IntPointer& pInt) : m_pInt(pInt)
> {
> }
>
> virtual Test()
> {
> }
>
> const IntPointer& m_pInt;
>
>};
>
>int main()
>{
> int x = 0xFF;
>
> CTestClass Test(&x);
>
> printf("&x = %p, Test.m_pInt = %p\n", &x, Test.m_pInt);
>
> // Note the different address
>
>// *Test.m_pInt = 0; // CRASH
>
> return 0;
>}
>
>------
>
>This is the output with optimizations (note the different addresses):
>
>D:\>cl /O2 Test.cpp & test
>Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
>[...]
>
>&x = 0012FEE4, Test.m_pInt = 000000FF
>
>
>This is the output without optimizations:
>
>D:\>cl Test.cpp & test
>Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
>[...]
>
>&x = 0012FED8, Test.m_pInt = 0012FED8
>
>
>I have been able to determine that the following criteria are necessary:
>
>- class has a vtable
>- constructor is inline
>- variable is passed as a reference
>
>Turning off global optimizations /Og or inlining prevents the issue. This
>happens on VC6.0 SP6 as well as VC7.1.
>
>I don't believe I am doing anything illegal.
You're binding the pointer produced by &x to a const reference. This is a
temporary pointer, and it goes away at the end of the statement:
CTestClass Test(&x);
This invalidates Test's m_pInt member, which is a reference bound to the
temporary, and so using m_pInt once the ctor returns is undefined. My rule
of thumb regarding const reference parameters is to never copy them to a
reference member or other long-lived reference variable, which avoids this
problem. Non-const reference parameters don't suffer from this problem in a
conformant compiler, because such a compiler disallows binding a temporary
to a non-const reference.
Why don't you simply pass the pointer by value? I hope you realize that:
CTestClass(const IntPointer& pInt)
means:
CTestClass(IntPointer const & pInt)
or simply:
CTestClass(int* const & pInt)
I don't see what using a reference buys you here.
-- Doug Harrison Microsoft MVP - Visual C++
- Next message: Tomas Restrepo \(MVP\): "Re: C3830 error appeared for no apparent reason?"
- Previous message: Brian Ross: "Optimizer bug (VC6 and VC7.1)?"
- In reply to: Brian Ross: "Optimizer bug (VC6 and VC7.1)?"
- Next in thread: Brian Ross: "Re: Optimizer bug (VC6 and VC7.1)?"
- Reply: Brian Ross: "Re: Optimizer bug (VC6 and VC7.1)?"
- Messages sorted by: [ date ] [ thread ]
Relevant Pages
|