This is the mail archive of the
gcc-prs@gcc.gnu.org
mailing list for the GCC project.
c++/93: Re: statement expressions implement incorrect copy semantics
- To: gcc-gnats at sourceware dot cygnus dot com
- Subject: c++/93: Re: statement expressions implement incorrect copy semantics
- From: "Martin v. Loewis" <martin at loewis dot home dot cs dot tu-berlin dot de>
- Date: Thu, 9 Mar 2000 11:11:14 +0100
- References: <64246316.24708bca@aol.com>
- Resent-Cc: gcc-prs at gcc dot gnu dot org, kosak at cs dot cmu dot edu
- Resent-Reply-To: gcc-gnats@gcc.gnu.org, "Martin v. Loewis" <martin@loewis.home.cs.tu-berlin.de>
>Number: 93
>Category: c++
>Synopsis: statement expressions implement incorrect copy semantics
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: analyzed
>Class: wrong-code
>Submitter-Id: net
>Arrival-Date: Thu Mar 09 02:16:01 PST 2000
>Closed-Date:
>Last-Modified:
>Originator: Seapig6@aol.com
>Release: 2.95.2
>Organization:
>Environment:
>Description:
Original-Message-ID: <64246316.24708bca@aol.com>
Date: Sun, 16 May 1999 16:59:54 EDT
[If you need to contact me, please use kosak@cs.cmu.edu ]
I don't know if the statement expression extension is deprecated. If not,
there is a problem with it under C++. I first noticed it in code like this:
% cat b2.cc && g++ -v && g++ b2.cc && echo done && a.out
#include <iostream.h>
#include <string>
int main()
{
string c;
c=({
string d("cow");
d;
});
cout <<"c is " <<c <<endl;
return 0;
}
Reading specs from
/afs/cs.cmu.edu/project/cmcl-kosak/various-gcc/egcs-19990502/
i386_linux3/lib/gcc-lib/i686-pc-linux-gnu/egcs-2.93.21/specs
gcc version egcs-2.93.21 19990502 (gcc2 ss-980929 experimental)
done
Segmentation fault
The above demonstrates the bug, but code like the following is easier to
analyze:
#include <iostream.h>
struct cow {
char x[1024];
cow() { Print(__PRETTY_FUNCTION__); }
~cow() { Print(__PRETTY_FUNCTION__); }
cow(const cow &other) { Print(__PRETTY_FUNCTION__); }
cow &operator=(const cow &other) {
Print(__PRETTY_FUNCTION__);
cout << "other is " << &other <<endl;
return *this;
}
void Print(const char *s) {
cout << s << ", this is " <<this <<endl;
}
};
int main()
{
cow c;
c=({
cow d;
d;
});
return 0;
}
Reading specs from
/afs/cs.cmu.edu/project/cmcl-kosak/various-gcc/egcs-19990502/
i386_linux3/lib/gcc-lib/i686-pc-linux-gnu/egcs-2.93.21/specs
gcc version egcs-2.93.21 19990502 (gcc2 ss-980929 experimental)
cow::cow(), this is 0xbffff898
cow::cow(), this is 0xbffff498
cow::~cow(), this is 0xbffff498
struct cow & cow::operator =(const cow &), this is 0xbffff898
other is 0xbffff098
cow::~cow(), this is 0xbffff098
cow::~cow(), this is 0xbffff898
Notice the destruction of 0xbffff098, an object that was never constructed!!
Looking at the generated assembly we learn that this object is a compiler
temporary that was created by a bitwise copy(!!), even though both a copy
constructor and operator= are defined for this object. The object was made
deliberately "big" so the bitwise copy code is easy to find:
% g++ -S bug.cc && cat bug.s
[...]
.LCFI7:
call _._3cow
addl $16,%esp
leal -3072(%ebp),%edi
leal -2048(%ebp),%esi
cld
movl $256,%ecx
rep
movsl
This bitwise copy should never have happened, and is no doubt the reason for
the segmentation fault in the "string" code example at the top of this report.
>How-To-Repeat:
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted: