C++ extension "cast-as-lvalues": time to deprecate?

Fergus Henderson fjh@cs.mu.OZ.AU
Mon May 12 17:58:00 GMT 2003


On 12-May-2003, Mark Mitchell <mark@codesourcery.com> wrote:
> > But what, exactly, are we warning about?  Consider the following program:
> >
> > --------------------------------------
> > #include <iostream>
> >
> > void foo(int&) {
> >     std::cout << "foo(int&) called\n";
> > }
> >
> > void foo(const int&) {
> >     std::cout << "foo(const int&) called\n";
> > }
> >
> > int main(int, char**) {
> >     unsigned u = 0;
> >     foo((int)u);
> > }
> 
> Oh, ugh, I didn't know we mishandled that.  That's just a bug;

Definitely.  It sort of half works in cases like the one above,
when the cast is to a different type with the same size,
but fails completely when casting from types with different
sizes.  E.g. if you change `unsigned' to `long long',
and add an assignment to `r' in the non-const version of foo(),
you'll see that the assignment only overwrites part of `u'.

	#include <iostream>

	void foo(int& r) {
	    std::cout << "foo(int&) called\n";
	    r = 0x1234;
	}

	void foo(const int& r) {
	    std::cout << "foo(const int&) called\n";
	}

	int main(int, char**) {
	    long long u = 0xaaaabbbbccccddddLL;
	    foo((int)u);
	    std::cout << "u = 0x" << std::hex << std::u << endl;
	}

This program outputs "u = 0xaaaabbbb00001234".
In contrast, if the assignment is done directly,

	int main(int, char**) {
	    long long u = 0xaaaabbbbccccddddLL;
	    (int)u = 0x1234;
	    std::cout << "u = 0x" << std::hex << std::u << endl;
	}

it outputs "u = 0x1234".

-- 
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
The University of Melbourne         |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.



More information about the Gcc mailing list