[Bug c++/31961] New: Premature hiding of symbols makes a copy constructor shooting at its own foot

waldemar dot rachwal at gmail dot com gcc-bugzilla@gcc.gnu.org
Wed May 16 17:38:00 GMT 2007


When I create an object using copy constructor syntax, giving it other object
of that type and (crucial) the same name as the object just being
constructed... the compiler treats that "other" object as the object being
constructed(!) Similar effects I get with the builtin data types.

Below is the short program demonstrating this (IMO) weird behavior with
associated embedded Makefile and two sample outputs (#if 0--commented).

I couldn't find anything about this issue in the standard (draft), but thinking
about it deeper since yesterday I couldn't discover any reasonable
*application* of such a semantic assuming it was valid. Similar effects with
builtin data types may be a dangerous trap for programmers. At least it's very
unsafe.

Even if g++ gives at last warnings, they appear only when I've added (sic!)
-O1, -O2... options which should have had nothing with the problem encountered
(note that in all my tests I tend to use -Wall -Wextra -pedantic -ansi as a
basis).

On the other hand, in oppose to semantics/behavior I observe with g++, I have
the strong rationale for semantics I expect (in case the standard says nothing
or leave it up to compiler implementators).

I get the problem with 4.1.1 on Solaris, with 3.4.4 on Cygwin as well, so I
think it might be quite general problem (if not solved yet).

Regards,
WR.

code snippet:

// premature-hiding.cpp

// SUBJECT:
//   Premature hiding of symbols makes copy constructor shooting at its own
foot.

// SYNOPSIS:
//   void fun (Seq& seq)  // <- (o)uter symbol
//   {
//       Seq seq(seq);    // symbols legend: (i)nner, (o)uter
//       //   ^i  ^o      // **EXPECTED**
//       //   ^i  ^i      // *G++ACTUAL** :(
//       ...
//   }

#include <iostream>

using namespace std;

class X {
public:
    X ();
    // In my original application I intentionally use non-const argument,
    // but here I put const variant, because:
    // 1) both give the same result, and
    // 2) const one looks more severe, as usually assiociated with "copying".
    explicit X (const X& rhs);
    ~X ();
private:
    int dummy;
};

inline X::X ()
{
    cout << "this ==> " << this << endl;
}

inline X::X (const X& rhs)
{
    cout << "&rhs ++> " << &rhs << endl;
    cout << "this oo> " << this << endl;
}

X::~X ()
{
    cout << "~obj ~~> " << this << endl;
}

int main ()
{
    // Weird behavior is observed already
    // when dealing with simple builtin types.

    cout << endl << "// int n = n + 1;" << endl;
    int n = n + 1;
    cout << "n ==> " << n << endl;

    cout << endl << "// double r = r + 1000.0;" << endl;
    double r = r + 1000.0;
    cout << "r ==> " << r << endl;

    //
    // auto object(s)
    //
    cout << endl << "// X obj;" << endl;
    {
        // Object 'obj' defined. It should be visible by code that follows.
        X obj;

        cout << "//   X obj(obj);" << endl;
        {
            // Object of the same name defined in nested scope
            // is expected to be properly "chained" with the parent object
            // of the outer scope.
            // Unfortunately it doesn't happen :( and GCC
            // allows an object being constructed to "copy" over itself.
            // It looks the symbol is introduced to symbol table
            // on '(' paren, but should be on ')'.
            // The latter (IMO proper) approach should only compile
            // if there is a symbol of that name already defined
            // somewhere earlier (not necessarily in nested {} as in my
example)
            // and lexically visible.
            X obj(obj);         // <***** UNEXPECTED BEHAVIOR

            cout << "//     X obj(obj);" << endl;
            {
                // Trying the same on the next (3rd in turn) level...
                X obj(obj);     // <***** UNEXPECTED BEHAVIOR (as above)
            }
        }
    }

    //
    // heap object(s)
    //
    cout << endl << "// X *ptr = new X(*ptr);" << endl;
    X *ptr = new X(*ptr);
    delete ptr;

    return 0;
}

#if 0 // ##### Makefile ##################################################
CXX = g++
CXXFLAGS = -g -Wall -Wextra -pedantic -ansi $(EXTFLAGS)

program := premature-hiding

$(program): $(program).cpp Makefile
        $(CXX) -o $@ $(CXXFLAGS) $<

run: $(program)
        @./$(program)

clean:
        -rm $(program) $(program).exe *.o *.s *.ii
#endif

#if 0 // ##### examining flags ###########################################
make -B CXXFLAGS=       # clean compile, initial surprise
make -B                 # clean too(!!), big surprise
make -B EXTFLAGS='-O1'  # warnings, but compiles (why it has anything with -O1
?!)
#endif

#if 0 // ##### g++ (GCC) 4.1.1 [sun4u] ###################################

// int n = n + 1;
n ==> 67481

// double r = r + 1000.0;
r ==> 1.96794e+307

// X obj;
this ==> 0xffbfefc8
//   X obj(obj);
&rhs ++> 0xffbfefc4     <****** UNEXPECTED
this oo> 0xffbfefc4
//     X obj(obj);
&rhs ++> 0xffbfefc0     <****** UNEXPECTED
this oo> 0xffbfefc0
~obj ~~> 0xffbfefc0
~obj ~~> 0xffbfefc4
~obj ~~> 0xffbfefc8

// X *ptr = new X(*ptr);
&rhs ++> 0
this oo> 0x214d8
~obj ~~> 0x214d8
#endif

#if 0 // ##### g++ (GCC) 3.4.4 [cygwin] ##################################

// int n = n + 1;
n ==> 1628302664

// double r = r + 1000.0;
r ==> 1000

// X obj;
this ==> 0x22ccb0
//   X obj(obj);
&rhs ++> 0x22cca0       <****** UNEXPECTED
this oo> 0x22cca0
//     X obj(obj);
&rhs ++> 0x22cc90       <****** UNEXPECTED
this oo> 0x22cc90
~obj ~~> 0x22cc90
~obj ~~> 0x22cca0
~obj ~~> 0x22ccb0

// X *ptr = new X(*ptr);
&rhs ++> 0x4
this oo> 0x6c0768
~obj ~~> 0x6c0768
#endif


-- 
           Summary: Premature hiding of symbols makes a copy constructor
                    shooting at its own foot
           Product: gcc
           Version: 4.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: waldemar dot rachwal at gmail dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31961



More information about the Gcc-bugs mailing list