* [Bug c++/39934] Union member incorrectly disallowed
2009-04-27 20:30 [Bug c++/39934] New: Union member incorrectly disallowed terra at gnome dot org
@ 2009-04-27 20:49 ` paolo dot carlini at oracle dot com
2009-11-03 5:45 ` redhatter at gentoo dot org
` (9 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: paolo dot carlini at oracle dot com @ 2009-04-27 20:49 UTC (permalink / raw)
To: gcc-bugs
------- Comment #1 from paolo dot carlini at oracle dot com 2009-04-27 20:49 -------
For the record, Comeau and Intel are not happy, though.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39934
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug c++/39934] Union member incorrectly disallowed
2009-04-27 20:30 [Bug c++/39934] New: Union member incorrectly disallowed terra at gnome dot org
2009-04-27 20:49 ` [Bug c++/39934] " paolo dot carlini at oracle dot com
@ 2009-11-03 5:45 ` redhatter at gentoo dot org
2009-11-03 13:33 ` redi at gcc dot gnu dot org
` (8 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: redhatter at gentoo dot org @ 2009-11-03 5:45 UTC (permalink / raw)
To: gcc-bugs
------- Comment #2 from redhatter at gentoo dot org 2009-11-03 05:45 -------
Also confirmed on GCC 3.4.5 as distributed with Qt SDK:
EzeCorp@TOSHIBA /tmp
$ /c/Qt/2009.03/mingw/bin/gcc --version
gcc.exe (GCC) 3.4.5 (mingw-vista special r3)
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
EzeCorp@TOSHIBA /tmp
$ cat test.c
struct A {
const int x;
int y;
};
union U {
const int x;
struct A a;
};
EzeCorp@TOSHIBA /tmp
$ gcc -o test-c.o -c test.c
EzeCorp@TOSHIBA /tmp
$ echo $?
0
EzeCorp@TOSHIBA /tmp
$ g++ -o test-cpp.o -c test.c
test.c:8: error: member `A U::a' with copy assignment operator not allowed in
union
EzeCorp@TOSHIBA /tmp
$ echo $?
1
Is there a sane workaround for this?
--
redhatter at gentoo dot org changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |redhatter at gentoo dot org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39934
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug c++/39934] Union member incorrectly disallowed
2009-04-27 20:30 [Bug c++/39934] New: Union member incorrectly disallowed terra at gnome dot org
2009-04-27 20:49 ` [Bug c++/39934] " paolo dot carlini at oracle dot com
2009-11-03 5:45 ` redhatter at gentoo dot org
@ 2009-11-03 13:33 ` redi at gcc dot gnu dot org
2009-11-03 13:47 ` terra at gnome dot org
` (7 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: redi at gcc dot gnu dot org @ 2009-11-03 13:33 UTC (permalink / raw)
To: gcc-bugs
------- Comment #3 from redi at gcc dot gnu dot org 2009-11-03 13:32 -------
(In reply to comment #2)
>
> Is there a sane workaround for this?
Don't use 'const' members of unions.
Union members cannot have a non-trivial copy assignment operator.
The assignment operator for A cannot be implicitly defined, as the const member
would make the program ill-formed.
I'm not sure whether using A in a union causes the implicitly-declared copy
assignment operator to be implicitly defined, but that seems to be what's
happening.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39934
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug c++/39934] Union member incorrectly disallowed
2009-04-27 20:30 [Bug c++/39934] New: Union member incorrectly disallowed terra at gnome dot org
` (2 preceding siblings ...)
2009-11-03 13:33 ` redi at gcc dot gnu dot org
@ 2009-11-03 13:47 ` terra at gnome dot org
2009-11-03 14:21 ` redi at gcc dot gnu dot org
` (6 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: terra at gnome dot org @ 2009-11-03 13:47 UTC (permalink / raw)
To: gcc-bugs
------- Comment #4 from terra at gnome dot org 2009-11-03 13:47 -------
> I'm not sure whether using A in a union causes the implicitly-declared copy
> assignment operator to be implicitly defined, but that seems to be what's
> happening.
No, that's not quite it.
The requirement for union members is that there cannot be a non-trivial copy
assignment operator.
gcc uses a different rule: it insists that there be a default copy assignment
operator.
Presumably someone thought those two formulations were the same. But they
are not: struct A doesn't have a copy assignment operator at all.
For the record, this kind of code occurs fairly naturally in C when creating
trees with different node types, tagged here by "x". The problems arise when
C++ code needs to interface with that C code.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39934
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug c++/39934] Union member incorrectly disallowed
2009-04-27 20:30 [Bug c++/39934] New: Union member incorrectly disallowed terra at gnome dot org
` (3 preceding siblings ...)
2009-11-03 13:47 ` terra at gnome dot org
@ 2009-11-03 14:21 ` redi at gcc dot gnu dot org
2009-11-03 17:44 ` terra at gnome dot org
` (5 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: redi at gcc dot gnu dot org @ 2009-11-03 14:21 UTC (permalink / raw)
To: gcc-bugs
------- Comment #5 from redi at gcc dot gnu dot org 2009-11-03 14:21 -------
(In reply to comment #4)
> > I'm not sure whether using A in a union causes the implicitly-declared copy
> > assignment operator to be implicitly defined, but that seems to be what's
> > happening.
>
> No, that's not quite it.
>
> The requirement for union members is that there cannot be a non-trivial copy
> assignment operator.
>
> gcc uses a different rule: it insists that there be a default copy assignment
> operator.
>
> Presumably someone thought those two formulations were the same.
Use the source, Luke:
if (TYPE_HAS_COMPLEX_ASSIGN_REF (type))
error ("member %q+#D with copy assignment operator not allowed in
union"
,
field);
/* Nonzero if there is a user-defined X::op=(x&) for this class. */
#define TYPE_HAS_COMPLEX_ASSIGN_REF(NODE) (LANG_TYPE_CLASS_CHECK
(NODE)->has_com
plex_assign_ref)
Now there could be a bug there, but it superficially looks right, and does not
look as though anyone thought the two formulations are the same.
> But they
> are not: struct A doesn't have a copy assignment operator at all.
It might not be defined, but one is declared, according to [class.copy]/10
"If the class definition does not explicitly declare a copy assignment
operator, one is declared implicitly."
> For the record, this kind of code occurs fairly naturally in C when creating
> trees with different node types, tagged here by "x". The problems arise when
> C++ code needs to interface with that C code.
The fact there are problems doesn't mean g++ is wrong.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39934
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug c++/39934] Union member incorrectly disallowed
2009-04-27 20:30 [Bug c++/39934] New: Union member incorrectly disallowed terra at gnome dot org
` (4 preceding siblings ...)
2009-11-03 14:21 ` redi at gcc dot gnu dot org
@ 2009-11-03 17:44 ` terra at gnome dot org
2009-11-03 17:49 ` paolo dot carlini at oracle dot com
` (4 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: terra at gnome dot org @ 2009-11-03 17:44 UTC (permalink / raw)
To: gcc-bugs
------- Comment #6 from terra at gnome dot org 2009-11-03 17:44 -------
cp/class.c has code like this:
/* If any field is const, the structure type is pseudo-const. * /
if (CP_TYPE_CONST_P (type))
{
...
/* ARM $12.6.2: [A member initializer list] (or, for an
aggregate, initialization by a brace-enclosed list) is the
only way to initialize nonstatic const and references
members. */
TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1;
}
The ARM comment (as quoted) is clearly wrong: offhand, I can think of
two other ways of getting an object initialized. There are probably
more.
1. Casting the offending "const" away. (Note that struct A is a plain
old C type -- data members only.)
// Make an object of type A.
A *pa = (A *)malloc (sizeof (A));
*const_cast<int *>(&pa->x) = 42;
pa->y = 42;
2. Copying an existing object.
A a (*pa);
I don't see the justification for setting TYPE_HAS_COMPLEX_ASSIGN_REF,
just for prohibiting assignment. That's pretty much the mixup I was
claiming in comment 4.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39934
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug c++/39934] Union member incorrectly disallowed
2009-04-27 20:30 [Bug c++/39934] New: Union member incorrectly disallowed terra at gnome dot org
` (5 preceding siblings ...)
2009-11-03 17:44 ` terra at gnome dot org
@ 2009-11-03 17:49 ` paolo dot carlini at oracle dot com
2009-11-03 18:10 ` redi at gcc dot gnu dot org
` (3 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: paolo dot carlini at oracle dot com @ 2009-11-03 17:49 UTC (permalink / raw)
To: gcc-bugs
------- Comment #7 from paolo dot carlini at oracle dot com 2009-11-03 17:49 -------
Saying that ARM is "wrong" seems frankly rather silly to me: either the
quotation is incorrect, I don't think so, or ARM has been obsoleted by the ISO
Standard, perfectly possible.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39934
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug c++/39934] Union member incorrectly disallowed
2009-04-27 20:30 [Bug c++/39934] New: Union member incorrectly disallowed terra at gnome dot org
` (6 preceding siblings ...)
2009-11-03 17:49 ` paolo dot carlini at oracle dot com
@ 2009-11-03 18:10 ` redi at gcc dot gnu dot org
2009-11-04 14:41 ` redi at gcc dot gnu dot org
` (2 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: redi at gcc dot gnu dot org @ 2009-11-03 18:10 UTC (permalink / raw)
To: gcc-bugs
------- Comment #8 from redi at gcc dot gnu dot org 2009-11-03 18:10 -------
(In reply to comment #6)
>
> The ARM comment (as quoted) is clearly wrong: offhand, I can think of
> two other ways of getting an object initialized. There are probably
> more.
>
> 1. Casting the offending "const" away. (Note that struct A is a plain
> old C type -- data members only.)
It's irrelevant that it has data members only. Casting away const on an object
declared const is undefined behaviour.
> 2. Copying an existing object.
>
> A a (*pa);
Copy construction is dealt with separately from copy assignment, so
has_complex_assign_ref is not relevant in this case.
So the ARM comment may be incorrect, but not due to either of your reasons.
As I said earlier, I'm not sure whether using A in a union causes the
implicitly-declared copy assignment operator to be implicitly defined. This
issue hinges on that point, not on the points you've been making.
The standard is clear that a copy assignment operator is implicitly-declared.
If it is implicitly defined then that copy assignment operator would be
ill-formed.
So the only question is whether using the type in a union causes it to be
implicitly defined.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39934
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug c++/39934] Union member incorrectly disallowed
2009-04-27 20:30 [Bug c++/39934] New: Union member incorrectly disallowed terra at gnome dot org
` (7 preceding siblings ...)
2009-11-03 18:10 ` redi at gcc dot gnu dot org
@ 2009-11-04 14:41 ` redi at gcc dot gnu dot org
2009-11-04 15:28 ` redi at gcc dot gnu dot org
2010-09-16 18:54 ` dherring at tentpost dot com
10 siblings, 0 replies; 14+ messages in thread
From: redi at gcc dot gnu dot org @ 2009-11-04 14:41 UTC (permalink / raw)
To: gcc-bugs
------- Comment #9 from redi at gcc dot gnu dot org 2009-11-04 14:41 -------
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#653
and
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#683
and
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2762
I'm still not sure what should happen though, I might ask on the std reflector.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39934
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug c++/39934] Union member incorrectly disallowed
2009-04-27 20:30 [Bug c++/39934] New: Union member incorrectly disallowed terra at gnome dot org
` (8 preceding siblings ...)
2009-11-04 14:41 ` redi at gcc dot gnu dot org
@ 2009-11-04 15:28 ` redi at gcc dot gnu dot org
2010-09-16 18:54 ` dherring at tentpost dot com
10 siblings, 0 replies; 14+ messages in thread
From: redi at gcc dot gnu dot org @ 2009-11-04 15:28 UTC (permalink / raw)
To: gcc-bugs
------- Comment #10 from redi at gcc dot gnu dot org 2009-11-04 15:28 -------
To be clear: In C++0x struct A would have a deleted copy assign operator, and
union U would be allowed, but its copy assignment operator would be deleted.
IMHO C++03 is not clear whether struct A has a trivial assignment operator or
not.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39934
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug c++/39934] Union member incorrectly disallowed
2009-04-27 20:30 [Bug c++/39934] New: Union member incorrectly disallowed terra at gnome dot org
` (9 preceding siblings ...)
2009-11-04 15:28 ` redi at gcc dot gnu dot org
@ 2010-09-16 18:54 ` dherring at tentpost dot com
10 siblings, 0 replies; 14+ messages in thread
From: dherring at tentpost dot com @ 2010-09-16 18:54 UTC (permalink / raw)
To: gcc-bugs
------- Comment #11 from dherring at tentpost dot com 2010-09-16 18:54 -------
FWIW, the example given in the C++ draft spec, section 9.5, fails to compile in
g++, even under version 4.5 with the -std=c++0x flag. (This example has been
there for a few years.)
Coupled with requirements such as operator= must be a nonstatic member
function, this restriction is a real annoyance.
--
dherring at tentpost dot com changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |dherring at tentpost dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39934
^ permalink raw reply [flat|nested] 14+ messages in thread