Subject: [Boost-bugs] [Boost C++ Libraries] #1851: Issue with proxies and rvalues
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2008-04-23 18:21:18
#1851: Issue with proxies and rvalues
--------------------------+-------------------------------------------------
Reporter: dave | Owner:
Type: Bugs | Status: new
Milestone: Boost 1.36.0 | Component: None
Version: Boost 1.35.0 | Severity: Problem
Keywords: |
--------------------------+-------------------------------------------------
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 <class Policies>
inline proxy<Policies> const&
proxy<Policies>::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<Policies>::operator=(proxy& const) function a non constant
member function. By changing:
inline proxy<Policies> const& proxy<Policies>::operator=(typename
proxy::assignment_self rhs) const
To:
:inline proxy<Policies> const& proxy<Policies>::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<Policies>::operator=" matches the
specified type
inline proxy<Policies> const& proxy<Policies>::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
}}}
--
Ticket URL: <http://svn.boost.org/trac/boost/ticket/1851>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:49:57 UTC