From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22185 invoked by alias); 16 May 2007 17:04:50 -0000 Received: (qmail 22141 invoked by uid 48); 16 May 2007 17:04:34 -0000 Date: Wed, 16 May 2007 17:04:00 -0000 Subject: [Bug c++/31960] New: Premature hiding of symbols makes a copy constructor shooting at its own foot X-Bugzilla-Reason: CC Message-ID: Reply-To: gcc-bugzilla@gcc.gnu.org To: gcc-bugs@gcc.gnu.org From: "waldemar dot rachwal at gmail dot com" Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2007-05/txt/msg01223.txt.bz2 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 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=31960