7

What happens here:

double foo( const double& x ) {
   // do stuff with x
}

foo( 5.0 );
  1. Does the compiler create an anonymous variable and sets its value to 5.0?
  2. Does the x reference a memory location in read-only memory? This is a weird phrasing, I know...

edit: I forgot the const keyword...

Gilad Naor
  • 20,752
  • 14
  • 46
  • 53

2 Answers2

6

A temporary variable is created for this purpose and it's usually created on stack.

You could try to const_cast, but it's pontless anyway, since you can no longer access a variable once the function returns.

sharptooth
  • 167,383
  • 100
  • 513
  • 979
  • This seems very inefficient to me. Wouldn't it be better to just create a memory location in Read Only segment with the declared value and use it instead of creating a variable on the stack? All behind the scenes, of course... – Gilad Naor Mar 19 '09 at 07:23
  • That's implementation dependent anyway. And double is not that large. – sharptooth Mar 19 '09 at 07:26
  • Temporary variable creation holds good for Objects as well. Instead of double if it were a Class then a temporary object would have got created and its constructor also would have got called. – aJ. Mar 19 '09 at 07:28
  • The question is specific to primitives. Creating a variable on the stack seems like a bit of waste, not just the memory (in case of recursion, maybe?!?!), but run-time wise as well. I guess implementation dependent is all there is... – Gilad Naor Mar 19 '09 at 07:32
  • Not necessarily such a waste. If you pass a value allocated in static storage the code that accesses it will have to read it and this can reduce cache locality. – sharptooth Mar 19 '09 at 07:53
1
  1. What compiler probably does create const literal, but that's not a variable.
  2. A non-const reference cannot point to a literal.

    $ g++ test.cpp test.cpp: In function int main()': test.cpp:10: error: invalid initialization of non-const reference of type 'double&' from a temporary of type 'double' test.cpp:5: error: in passing argument 1 ofdouble foo(double&)'

test.cpp:

#include <iostream>

using namespace std;

double foo(double & x) {
    x = 1;
}

int main () {
    foo(5.0);

    cout << "hello, world" << endl;
    return 0;
}

On the other hand, you could pass a literal to a const reference as follows. test2.cpp:

#include <iostream>

using namespace std;

double foo(const double & x) {
    cout << x << endl;
}

int main () {
    foo(5.0);

    cout << "hello, world" << endl;
    return 0;
}
Eugene Yokota
  • 94,654
  • 45
  • 215
  • 319