Topic: Symantec C++ optimisation wrong?


Author: William McIlhagga <william.mc@pi.se>
Date: 1995/07/27
Raw View
jason@cygnus.com (Jason Merrill) wrote:
>
> >>>>> Alan Griffiths <aGriffiths@ma.ccngroup.com> writes:
> > This optimisation is permitted (temp may be constructed
> > in the place of the return value).
>
> No, it can't.  Both temp and Test must be constructed and (trivially)
> destroyed, since they are named objects.  Only temporaries can be elided.
>
> Jason

Yeah, I agree. Stroustrup says that you can only get rid of temps if
the _only_ way this can be discovered is by side effects of temp
ctor/dtor e.g. print statements. But surely the value of a member
variable can't be classed as a side effect. I think the symantec
compiler just checks to see if the temp and the constructing object
are the same type, and if so it does a construct-in-place. But that
means that the ctor code is never called, so things can screw up
badly sometimes.





Author: William McIlhagga <william.mc@pi.se>
Date: 1995/07/25
Raw View
I came across the following example of a compiler
optimisation which radically alters the meaning of
a program.

The following program defines a class called ManyCtors
which has two copy ctors - the default and another that
takes an integer argument. There is a flag which is
set differently depending on which ctor is used.

-- program start --

#include <iostream.h>

class ManyCtors {
public:
 int flag;

 ManyCtors() { flag = 0; }

 ManyCtors( const ManyCtors& mn )
 {
   cout << "Default copy ctor\n";
   if (mn.flag==1) {
       cout << "flag 1\n";
       flag = 0;
       }
   else
       flag = 1;
 }

 ManyCtors( const ManyCtors& mn, int i)
 {
   cout << "Integer copy ctor\n";
   flag = i;
 }
};

ManyCtors fn( const ManyCtors& mn )
{
 ManyCtors temp(mn,1);
 cout << "temp.flag = " << temp.flag << endl;
 return temp;
}


void main()
{
 // this call not relevant to problem
 ios::sync_with_stdio();

 ManyCtors m1;
 ManyCtors test(fn(m1));

 cout << "Test.flag = " << test.flag << endl;

}

-- program end --

This was compiled and run using symantec c++ 6.1 for
Windows. The output was:

Integer copy ctor
temp.flag = 1
Test.flag = 1



This is wrong. The output should have been:

Integer copy ctor
temp.flag = 1
Default copy ctor
Test.flag = 0

assuming that the default copy from temp to fn's return
value has been eliminated. This is the sort of output
you get with Borland C++ 4.0.

It looks like Symantec's construct-in-place optimisation
is flawed. They seem to have assumed that the default
copy constructor won't ever need to do any additional
processing, and it can be optimised away any time. But
this isn't so, even in real world programs (e.g. LaPack++
has a copy which is conditional on a flag)

Any comments? What do other compilers do?






Author: Alan Griffiths <aGriffiths@ma.ccngroup.com>
Date: 1995/07/25
Raw View
In article <3v29cc$8m8@news.pi.se> william.mc@pi.se "William McIlhagga" writes:

> I came across the following example of a compiler
> optimisation which radically alters the meaning of
> a program.
>
> ...
>
> assuming that the default copy from temp to fn's return
> value has been eliminated. This is the sort of output
> you get with Borland C++ 4.0.

This optimisation is permitted (temp may be constructed
in the place of the return value).

--
Alan Griffiths  Senior Systems Consultant, CCN Group Limited





Author: jason@cygnus.com (Jason Merrill)
Date: 1995/07/25
Raw View
>>>>> Alan Griffiths <aGriffiths@ma.ccngroup.com> writes:

> In article <3v29cc$8m8@news.pi.se> william.mc@pi.se "William McIlhagga" writes:
>> I came across the following example of a compiler
>> optimisation which radically alters the meaning of
>> a program.
>>
>> ...
>>
>> assuming that the default copy from temp to fn's return
>> value has been eliminated. This is the sort of output
>> you get with Borland C++ 4.0.

> This optimisation is permitted (temp may be constructed
> in the place of the return value).

No, it can't.  Both temp and Test must be constructed and (trivially)
destroyed, since they are named objects.  Only temporaries can be elided.

Jason





Author: vbazarov@imsisoft.com (Victor Bazarov)
Date: 1995/07/25
Raw View
In article <3v29cc$8m8@news.pi.se>,
   William McIlhagga <william.mc@pi.se> wrote:
>I came across the following example of a compiler
>optimisation which radically alters the meaning of
>a program.
>
>The following program defines a class called ManyCtors
>which has two copy ctors - the default and another that
>takes an integer argument. There is a flag which is
>set differently depending on which ctor is used.
>
>-- program start --

[snip]

>It looks like Symantec's construct-in-place optimisation
>is flawed. They seem to have assumed that the default
>copy constructor won't ever need to do any additional
>processing, and it can be optimised away any time. But
>this isn't so, even in real world programs (e.g. LaPack++
>has a copy which is conditional on a flag)
>
>Any comments? What do other compilers do?
>

Microsoft C/C++ v8.0 (I only added "#include <iostream.h>" as a first line):

Integer copy ctor
temp.flag = 1
Default copy ctor
flag 1
Test.flag = 0

Victor.

--
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
If it's stupid, but works, it isn't stupid.
                                            Murphy
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-