This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Volatile MEMs in statement expressions and functions inlined astrees



On 14 Dec 2001, Alexandre Oliva wrote:
>
> Hmm...  How do you add class assignment operators into this picture?

Uhh.. You cannot. It doesn't apply.

If you override the assignment operator, then the rules of assignment are
defined by _you_, not by the C++ standard.  It's no longer an assignment,
it's just another random user-supplied operator.

For example, the C++ standard specifies that "the type of the result is
the type of the left side" (to pick the _one_ single thing that nobody has
yet argued about ;)

Yet you can easily create a class assignment operator where this simply
isn't true. So once you overload the assignment, the "standard" assignment
is no longer an issue. Forget about them.

Here's a trivial example that matches _none_ of the three now oft-quoted
requirements for "standard" assignments (and please, before anybody shoots
me for this offense against humanity, I'd like to point out that I have
never _ever_ done this in real life, and I don't encourage people to write
code like this):

	#include <stdio.h>

	class foo {
	public:
	        int i;
	        int operator=(int val) { i = val + 1; return val+2; }
	};

	foo p,q,r;

	int main(void)
	{
	        p = q = r = 1;
	        printf("%d %d %d\n", p.i, q.i, r.i);
	        return 0;
	}

Note: the "=" operation (which is no longer an assignment in the C++
sense, just another overloaded operator) violates all three rules of
"real" assignments:

 - the value it returns is _not_ the type of the left side (it returns an
   integer, and the type of the left side is obviously "foo&"

 - the value it returns is _not_ the value stored (it stored "val+1", yet
   returns "val+2")

 - the result of the assignment isn't even an lvalue (it's an "int", not a
   "int&", much less a "foo&").

Yet the above is, as far as I can tell, perfectly legal C++ code. When we
added the class assignment operator into the picture, we just threw out
all the rules and wrote our own.

And yes, I would expect the above to print out "6 4 2", and it does. We
have the sequence

	r = 1;		=> r.i takes the value 2, returns 3 =>
	q = 3;		=> q.i takes the value 4, returns 5 =>
	p = 5;		=> p.i takes the value 6, returns 7 => unused

and we're obviously not satisfying anybody. So clearly overloaded
assignment operators are even more "volatile" than real volatile memory.

You can obviously make the example even _more_ strange by mixing types:
you could make an integer assignment return a "foo&", and have a "foo&"
assignment return yet another type, and just basically try to confuse the
issues even more.

So I think (and this time I'm _positive_ that Gabriel will agree) that the
C++ assignment rules only cover the _standard_ assignments, not the ones
you come up with yourself by overloading the operator.

			Linus

PS. I don't know whether there is an "Obfuscated C++" competition or not,
but if there is, overloading of operators should be banned, simply because
it makes it too easy. It's like shooting fish in a barrel - it's just not
a sport any more.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]