[Bug c++/39934] Union member incorrectly disallowed
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=39934 Jonathan Wakely changed: What|Removed |Added CC||colu...@gmx-topmail.de --- Comment #14 from Jonathan Wakely --- *** Bug 64428 has been marked as a duplicate of this bug. ***
[Bug c++/39934] Union member incorrectly disallowed
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=39934 Jason Merrill jason at gcc dot gnu.org changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |FIXED Target Milestone|--- |4.6.4 --- Comment #13 from Jason Merrill jason at gcc dot gnu.org --- Agreed. Fixed with -std=c++0x in GCC 4.6.
[Bug c++/39934] Union member incorrectly disallowed
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=39934 Paolo Carlini paolo.carlini at oracle dot com changed: What|Removed |Added CC|gcc-bugs at gcc dot gnu.org|jason at gcc dot gnu.org, ||paolo.carlini at oracle dot com --- Comment #12 from Paolo Carlini paolo.carlini at oracle dot com --- Given that with -std=c++11 we now correctly accept this, I'm not sure we should still keep open the c++98 (rather pedantic IMHO) side of the issue. Jason?
[Bug c++/39934] Union member incorrectly disallowed
--- 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
[Bug c++/39934] Union member incorrectly disallowed
--- 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
[Bug c++/39934] Union member incorrectly disallowed
--- 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
[Bug c++/39934] Union member incorrectly disallowed
--- 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
[Bug c++/39934] Union member incorrectly disallowed
--- 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
[Bug c++/39934] Union member incorrectly disallowed
--- 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
[Bug c++/39934] Union member incorrectly disallowed
--- 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
[Bug c++/39934] Union member incorrectly disallowed
--- 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_castint *(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
[Bug c++/39934] Union member incorrectly disallowed
--- 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
[Bug c++/39934] Union member incorrectly disallowed
--- 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: ezec...@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. ezec...@toshiba /tmp $ cat test.c struct A { const int x; int y; }; union U { const int x; struct A a; }; ezec...@toshiba /tmp $ gcc -o test-c.o -c test.c ezec...@toshiba /tmp $ echo $? 0 ezec...@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 ezec...@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
[Bug c++/39934] Union member incorrectly disallowed
--- 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