Consider: struct X { X(); explicit X(const X&); }; void f(X); void g(const X&); int main() { X x; f(x); f(X()); g(x); g(X()); } We currently give errors for f(x), f(X()) and g(X()), but not g(x). This is not quite the behavior of EDG which allows g(X()). There are (at least) two pertinent cwg defect reports: 152 and 391. 152 has TC1 status (it is normative) and clarifies the behavior for f(), and is consistent with the bevavior of both gcc and EDG. Issue 391 addresses g() and (I believe) explains the discrepancy between gcc and EDG by specifying that X() will bind directly to the reference parameter of g() with no copy. This issue has been voted on in full committee and approved as a dr. However the next available time to make anything normative is C++0X. So 391 has been applied to the working draft, and EDG has apparently implemented it. I respectfully request that gcc implement it as well. The issue is non-controversial on the committee and is causing problems with client code today.
I am going to mark this depending on PR 12226 for a second since that is the PR 12226 which made promoted this change.
I am going to mark this a regression but not confirm it because I don't understand this issue fully and this seems like someone else who knows better about this should do that. CCing Mark as he did the change for PR 12226. Adding the URL for the DR report for lazy people (me): http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#391
More information: I now believe I unknowingly misled when I surmized that EDG had implemented cwg 391. If you declare the copy ctor private in the example, EDG rejects g(X()) based on accessibility. Rather I am now surmizing that there is wiggle room in 8.5.3 to allow EDG's behavior. More specifically, EDG is choosing this bullet: * The reference is bound to the object represented by the rvalue (see basic.lval) or to a sub-object within that object. And (I'm still guessing) this choice requires access checking of the copy ctor, but does not require an implicit copy ctor. Sorry my initial post wasn't more clear. This is a confusing area to me.
Subject: Re: [3.4/4.0/4.1 Regression] [DR 391] Reference binding and explicit copy constructors "pinskia at gcc dot gnu dot org" <gcc-bugzilla@gcc.gnu.org> writes: | I am going to mark this a regression but not confirm it because I don't before you declare something as a regression, please make sure you do understand the real issues. When you don't fully understand, please leave it alone and help somewhere else. Thanks. -- Gaby
(In reply to comment #4) > before you declare something as a regression, please make sure you do > understand the real issues. When you don't fully understand, please > leave it alone and help somewhere else. Thanks. Well Marking things as regression is easy as it is just easy to test it on different versions of GCC which I did. Now figuring out what we should do here is not up to me which is why I did not confirm it. Now I read the DR and the standard (well I did read it for the bug linked here) but it seems like the DR only resolves one part of the question but it seems raise differnet questions for me which is why I left it unconfirmed. Should have I written this first, maybe but then again you would have harped on me anyways. If you noticed I gave some back ground info on when the change happened and CCed the person who changed it to get a clarification (in fact I said that in comment #2). I linked to the DR report so that people could easier access to it instead of remembering the link each time when comming to this bug. (and now this whole thing is offtopic from the bug report).
At the risk of continuing off-topic... Thank you Andrew for your continuing prompt and high quality work. It is a very valuable service and I've never had any complaints with the way you provide it. Good Job and Thank You!
Subject: Re: [3.4/4.0/4.1 Regression] [DR 391] Reference binding and explicit copy constructors "pinskia at gcc dot gnu dot org" <gcc-bugzilla@gcc.gnu.org> writes: | (In reply to comment #4) | > before you declare something as a regression, please make sure you do | > understand the real issues. When you don't fully understand, please | > leave it alone and help somewhere else. Thanks. | | Well Marking things as regression is easy as it is just easy to test it on | different versions of GCC which I did. No, it is not that simple. For example consider access checking (which this issue is about). For a long time, GCC has been known to be buggy on access checking, therefore *wrongly* accepting codes it should reject (for example is the PR you referenced.) That was fixed by checking the accessibility of the copy constructor even when it is elided (as required by the C++ standard). The C++ Working Paper has been slightly changed recently -- but not the C++ standard -- to be somehow more permissisive in specific cases. This PR is based on the hypothesis that the working paper stays as it is on that point till we get the standard. The proper categorization is that this is a request for enhancement. -- Gaby
Changing to request for enhancement. The requested behaviour is a change in th working paper. Existing behaviour is what is required by the standard (even when it can be argued that checking for something that is elided is suboptimal.)
(In reply to comment #8) > Changing to request for enhancement. The requested behaviour is a change > in th working paper. Existing behaviour is what is required by the standard > (even when it can be argued that checking for something that is elided is > suboptimal.) Did you read comment 3?
So this really just DR 152 and has nothing to do with DR 391 except misleading us. DR 152 is TR1 so it is part of the standard, therefor this is still a regression and should be marked as normal severity.
Subject: Re: [3.4/4.0/4.1] [DR 391] Reference binding and explicit copy constructors "hhinnant at apple dot com" <gcc-bugzilla@gcc.gnu.org> writes: | ------- Comment #9 from hhinnant at apple dot com 2006-01-25 02:54 ------- | (In reply to comment #8) | > Changing to request for enhancement. The requested behaviour is a change | > in th working paper. Existing behaviour is what is required by the standard | > (even when it can be argued that checking for something that is elided is | > suboptimal.) | | Did you read comment 3? Yes. Is your claim that whether the copy constructor is converting or not does not matter? -- Gaby
Subject: Re: [3.4/4.0/4.1 Regression] [DR 152] Reference binding and explicit copy constructors "pinskia at gcc dot gnu dot org" <gcc-bugzilla@gcc.gnu.org> writes: | So this really just DR 152 No! DR 152 is about what happens when you pass an argument by value and the copy-constructor happens to be explicit. DR 152 says that well, you loose -- the copy-constructor is a converting constructor and if it is explicit, then the pass-by-value fails. Read the last sentence of bullet 1 and bullet 2 carefully. | and has nothing to do with DR 391 except misleading us. It is exactly the opposite. DR 152 is a distraction. The PR is about | DR 152 is TR1 if it were TR1, it would not have been the C++ standard. It is TC1, but again this issue is NOT about DR 152. It is about DR 391 and and related aspect. -- Gaby
(In reply to comment #11) > | Did you read comment 3? > > Yes. Is your claim that whether the copy constructor is converting or > not does not matter? No. My suspicion is that there is a 99.99% chance that EDG is conforming to C++03 in this regard. And furthermore, their behavior (which is different from ours) is preferable to our customers.
DR 391, not 392. My typo.
Actually DR 152 clarifies that this is invalid code. as Per 8.5/12 this is copy-initialization.
Subject: Re: [3.4/4.0/4.1] [DR 392] Reference binding and explicit copy constructors "hhinnant at apple dot com" <gcc-bugzilla@gcc.gnu.org> writes: | (In reply to comment #11) | > | Did you read comment 3? | > | > Yes. Is your claim that whether the copy constructor is converting or | > not does not matter? | | No. My suspicion is that there is a 99.99% chance that EDG is conforming to | C++03 in this regard. Further investigation reveals this: If an implementation chooses the second bullet (where it elects to copy the temporary to another temporary) what is the semantics? Is it copy-initialization as everywhere else in argument pass-by-value? Or is it direct-initialization? That is what my question meant. GCC always uses copy-initialization in function argument passing, except when the parameter directly binds, i.e. no temporary is needed. | And furthermore, their behavior (which is different from | ours) is preferable to our customers. I think I know where this PR comes from (move semantics simulation anyone? :-). My main objection is classifying it as regression. The issue would deserve a DR if we did not already have 391. -- Gaby
This is certainly not a P1 for 4.1. If it's a bug (it probably is, but I still want to think about it more), it's a minor one, in the grand scheme of things.
Subject: Re: [3.4/4.0/4.1] [DR 391] Reference binding and explicit copy constructors "mmitchel at gcc dot gnu dot org" <gcc-bugzilla@gcc.gnu.org> writes: | This is certainly not a P1 for 4.1. If it's a bug (it probably is, but I still | want to think about it more), it's a minor one, in the grand scheme of things. Howard raised the issue on the -core reflector. See c++std-core-11265 when Mike expessed the same opinion as me in previous comments. It is ill-formed in C++03 (GCC behaviour is correct). However, it is no longer the same behaviour after the last changes voted in the working paper. -- Gaby
This issue will not be resolved in GCC 4.1.0; retargeted at GCC 4.1.1.
*** Bug 12226 has been marked as a duplicate of this bug. ***
*** Bug 27295 has been marked as a duplicate of this bug. ***
Will not be fixed in 4.1.1; adjust target milestone to 4.1.2.
*** Bug 28365 has been marked as a duplicate of this bug. ***
*** Bug 28846 has been marked as a duplicate of this bug. ***
*** Bug 30959 has been marked as a duplicate of this bug. ***
*** Bug 31156 has been marked as a duplicate of this bug. ***
Subject: Bug 25950 Author: jason Date: Wed Oct 24 03:45:37 2007 New Revision: 129596 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=129596 Log: PR c++/25950 (DR 391) * call.c (struct conversion): Remove check_copy_constructor_p. (reference_binding): Always bind a reference directly to a compatible class rvalue. Pass down LOOKUP_NO_TEMP_BIND during temporary creation. (check_constructor_callable): Remove. (convert_like_real): Don't call it. (initialize_reference): Don't call check_constructor_callable. (standard_conversion): Check LOOKUP_NO_CONVERSION instead of LOOKUP_CONSTRUCTOR_CALLABLE. Don't require a temporary for base conversions if LOOKUP_NO_TEMP_BIND. (implicit_conversion): Pass through LOOKUP_NO_TEMP_BIND. (build_user_type_conversion_1): Pass through LOOKUP_NO_TEMP_BIND for second conversion. * cp-tree.h (LOOKUP_CONSTRUCTOR_CALLABLE): Remove. Added: trunk/gcc/testsuite/g++.dg/overload/reftemp1.C trunk/gcc/testsuite/g++.dg/overload/reftemp2.C Removed: trunk/gcc/testsuite/g++.dg/init/copy7.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/call.c trunk/gcc/cp/cp-tree.h
Fixed for 4.3.0.
Fixed in 4.3, no longer marked a regression; closing.
*** Bug 36490 has been marked as a duplicate of this bug. ***
*** Bug 260998 has been marked as a duplicate of this bug. *** Seen from the domain http://volichat.com Marked for reference. Resolved as fixed @bugzilla.