suprising behavior passing arguments as references


Consider the following do-nothing program

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class myclass { };

void foo(myclass &x)
{
}

void foobar(const myclass &x)
{
}

myclass create(void)
{
  myclass x;
  return x;
}

int main(void)
{
  foobar(create());
  foo(create());
}


It will not compile under gcc (4.6.3). I get the following error message:

test.cpp: In function ‘int main()’:
test.cpp:21:15: error: invalid initialization of non-const reference of type ‘myclass&’ from an rvalue of type ‘const myclass’
test.cpp:4:6: error: in passing argument 1 of ‘void foo(myclass&)’


It will compile with the call to foo() commented out. I do not understand why the const is allowing foobar to compile? Any ideas?

Thanks
The standard says that temporary objects (rvalues) can be bound to const references, but not to non-const references. The object returned by create() is a temporary object.
This happens because an r-value can be bound to a const reference, but not to a non-const reference. And a temporary unnamed object returned by the create() function is an r-value.
Sometimes it's funny when the answers come almost at the same time and are pretty much the same :)
By the way the code will be compiled successfully by MS VC++ 2010 if you will not switch off VC++ language extensions for the project.:)
I described peculiarities of the MS VC++ 2010 here

http://cpp.forum24.ru/?1-3-0-00000045-000-0-0-1343495846

Though the description is written in Russian.
Last edited on
Thanks. Of course the standard is what it is, but do you have any idea of the philosophy behind this particular rule? What are they protecting against with this behavior?
Consider a simple example

int x = 2, y = 3;
( x + y ) = 10;

If temporary values would be allowed to bind to non-const references you could write the code above.
Ah -- the light goes on. So, in MS VC++ 2010 the above is permissible. Interesting.

Thanks
Apart from own features MS VC++ 2010 has numerous bugs and it allows for example the following code

1
2
3
4
5
6
7
8
9
10
11
strcut A
{
   int x;
};

A f() { A a = {}; return a; }

int main()
{
   f().x = 10;
}
Topic archived. No new replies allowed.