id,summary,reporter,owner,description,type,status,milestone,component,version,severity,resolution,keywords,cc 1851,Issue with proxies and rvalues,Dave Abrahams,Dave Abrahams,"From https://premier.intel.com/premier/IssueDetail.aspx?IssueID=474910 : {{{ This bug appears in both the linux and Windows versions of the compiler. See attached preprocessed file. The problem appears to be in the obj_moveattr function: it should be calling the first assignment operator in boost::python::api::proxy template inline proxy const& proxy::operator=(typename proxy::assignment_self rhs) const { return *this = python::object(rhs); } but it is not, for some reason. You can see that by adding this->doesnotexist = 1; to the above function body, which *should* cause it to fail to compile, but does not. Issue Communication Reply to Issue Updated by Intel: 4/4/2008 7:04:10 PM David, The assignment operator in your example is not being applied to a const rvalue. The assignment operator is being called here: void obj_moveitem(object& x, object src, object dst) { x[dst] = x[src]; } Even if x was const, the subscript operators inside class object_operators return the type const_object_item - not const const_object_item. const_object_item operator[](object_cref) const; // this does not return a constant object_item operator[](object_cref); --mark Feedback from David Abrahams: 4/3/2008 9:16:01 PM I'm not so interested in G++ compatibility as standard conformance. If I understand you correctly, a regular (non-const) copy assignment operator applies to const rvalues as well as non-const ones? If so, that's very surprising. Updated by Intel: 4/2/2008 8:10:02 PM David, The difference between the Gnu and Intel behaviour can be seen if you add an explicit default assignment operator to the proxy class, i.e.: sptxl2-146> diff object.cpp nobject.cpp + + proxy& operator=(const proxy&) { + this->indefaultassignmentoperator = 1; + return *this; + } + Now both g++ and icpc have the same behaviour - they choose the above non constant default assignment operator over the user provided const assignment operator. (i.e neither compiler gives an error message about this->doesnotreallyexist but instead both compilers complain about this->indefaultassignmentoperator). So the difference between g++ and icpc is the following - icpc generates a default copy assignment operator (and chooses it as the best match) and g++ does not generate one. So which compiler is correct - should a default copy assignment operator be generated or not? According to the resolution of the core issue #574 the Intel compiler is doing the right thing, i.e.: > Since the point of the definition of copy assignment operator > is to control whether the compiler generates a default version if the > user doesn't, I suspect the correct answer is that neither const nor > volatile cv-qualification on operator= should be allowed for a copy > assignment operator. A user can write an operator= like that, but > it doesn't affect whether the compiler generates the default one. But of course the Intel compiler on Linux needs to match the Gnu behaviour so this is a bug on our part. --mark Feedback from David Abrahams: 4/1/2008 4:32:44 PM I'm sorry; I don't see what being a copy assignment operator has to do with it. The proxy object being assigned into is a const rvalue, and thus, IIUC, only a const member function can apply to it. If the default-generated copy assignment is a non-const function, it shouldn't be found. What am I missing? Updated by Intel: 3/27/2008 10:10:57 PM David, The development team just informed me that the Intel compiler is in fact doing the right thing per the language spec, but we will emulate gcc's behavior for compatibility purposes. To fix the code you should make the proxy::operator=(proxy& const) function a non constant member function. By changing: inline proxy const& proxy::operator=(typename proxy::assignment_self rhs) const To: :inline proxy const& proxy::operator=(typename proxy::assignment_self rhs) The compiler compiles the code. Thanks, --mark $ icc -c -w object.cpp ../../../boost/python/proxy.hpp(69): error: no instance of overloaded function ""boost::python::api::proxy::operator="" matches the specified type inline proxy const& proxy::operator=(typename proxy::assignment_self rhs) ^ compilation aborted for object.cpp (code 2) For further details please refer to issue #574 on the C++ standards core issues list, i.e.: 574. Definition of ""copy assignment operator"" Section: 12.8 [class.copy] Status: review Submitter: Steve Adamczyk Date: 15 April 2006 Is the following a ""copy assignment operator?"" struct A { const A& operator=(const A&) volatile; }; 12.8 [class.copy] paragraph 9 doesn't say one way or the other whether cv-qualifiers on the function are allowed. (A similar question applies to the const case, but I avoided that example because it seems so wrong one tends to jump to a conclusion before seeing what the standard says.) Since the point of the definition of ""copy assignment operator"" is to control whether the compiler generates a default version if the user doesn’’t, I suspect the correct answer is that neither const nor volatile cv-qualification on operator= should be allowed for a ""copy assignment operator."" A user can write an operator= like that, but it doesn't affect whether the compiler generates the default one. Updated by Intel: 3/25/2008 11:51:37 PM David, Thanks for the problem report and the test case. I reproduced the problem and filed a report on this issue. I will let you know when I get an update. --mark Intel Developer Support }}}",Bugs,closed,Boost 1.36.0,python USE GITHUB,Boost 1.35.0,Problem,invalid,,