Re: Optimizer bug (VC6 and VC7.1)?

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance

From: Doug Harrison [MVP] (dsh_at_mvps.org)
Date: 11/18/04


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++


Relevant Pages

  • Re: Why is the memory doubled when writing data to files?
    ... > records using a header that indicates the size of the record, ... a reference to Fis allowed to bugger up a subsequent ... > The simple fact is that a modern Fortran implementation is big. ... > unbounded number of optimizations are possible. ...
    (comp.lang.fortran)
  • Re: passing class to a function in c++ - performance question
    ... In practice, usually, passing by pointer vs by reference has the same ... optimizations with references vs optimizations with pointers. ... This also applies to the "register" keyword. ...
    (comp.lang.cpp)
  • Re: Automatic (?) array bounds checking
    ... function allocates a temporary v3, ... copies the values (or probably a reference?) to the array c. ... In order for them to be valid optimizations, ... array is really large), ...
    (comp.lang.fortran)
  • Re: Did GC eat my mutex? Why did Mutex need to be static?
    ... How can the GC collect it when it's reference is not stored somewhere? ... to do with the compiler and compiler optimizations, ... In your case there seems to be a valid reference because ... > Application.Run doens't return until the app quits and so mutex is a valid ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Question on LSP
    ... Sure, the developer must keep track of which type has been assigned to each pointer to manage complexity in creating the design, which is why the 'T' is in T*. ... Subtyping is a relation which does not ... Those object types are completely orthogonal to the semantics of being an object reference. ... aggregate references, is the aggregate of referenced objects or target ...
    (comp.object)