Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm reading Accelerated C++ and in Chapter 4 they bring up the concept of lvalues. There's an example of something that shouldn't work, but after trying it myself I found that it does indeed work.

Specifically they state that, given these functions:

// return an empty vector
vector<double> emptyvec()
{
  vector<double> v;
  return v;
}

// read things from an input stream into a vector<double>
// (I'm leaving out the function body here because it's irrelevant)
istream &read_things(istream& in, vector<double>& hw);

This should not be allowed:

read_stuff( cin, emptyvec() );

Because emptyvec() is an expression and returns a temporary object (a non-lvalue as they called it in the book). However, this not only compiles but actually runs (Windows 7/VisualStudio 2010).

So, what's going on? Was this just a bad example on the authors' part, or is there something else happening that I don't understand.

Thanks.

share|improve this question
    
Can you double check the return type of emptyvec()? As given (vector<double> vector) it doesn't make much sense. Was this vector<double> & in the book (in which case the code is indeed an example of the problem the book mentions)? –  jimwise Jan 24 '13 at 15:47
    
@jimwise That was a typo when I entered it here. The original program was actually written correctly :) –  Alex Jan 24 '13 at 16:07
    
Which way? Returning vector<double> or vector<double> &? –  jimwise Jan 24 '13 at 16:09
    
@jimwise (The original typo was vector<double> vector emptyvec() which is not valid syntax) I don't have the book here at the moment, but when I tried changing it from vector<double> to vector<double>& the compiler threw an error: warning C4172: returning address of local variable or temporary So that seems to be more in line with what the author was saying. –  Alex Jan 24 '13 at 16:12
add comment

2 Answers

up vote 1 down vote accepted

The concern the book mentions would come into play if the function was declared as:

vector<double> &emptyvec()

or

vector<double> *emptyvec()

as it would then be returning a temporary value by reference, and by the time you used the reference, the value it referred to would be gone. Your compiler should issue a warning or an error for this case, and you might (but might not) see a variety of possible failures at run time (sadly, the type of error you would see could vary widely).

On the other hand, if the function is indeed declared as

vector<double> emptyvec()

the vector is being returned by value (i.e. a copy of the actual vector is being made into wherever you store the return value), and the program should work correctly.

share|improve this answer
    
Ah yes, I just realized this after reading your earlier comment. So this was probably all down to me misreading the example in the book. The compiler throws an error now and I even get a runtime exception (access violation reading a memory location) and everything makes total sense now. Thanks for the help! –  Alex Jan 24 '13 at 16:17
    
Glad I could help! :-) –  jimwise Jan 24 '13 at 16:31
    
@Alex: Was it a typo in the book? Maybe it's worth contacting the author. –  FrustratedWithFormsDesigner Jan 24 '13 at 16:56
add comment

It's a compiler extension on the part of Visual Studio. The code should indeed not compile, and it won't on the other major compilers like GCC and Clang, as a temporary cannot bind to a mutable reference.

share|improve this answer
1  
The vector is passed by value, which is perfectly fine. –  tdammers Jan 24 '13 at 17:35
2  
Why the downvotes? He's right. This shouldn't compile according to the C++ standard. There's no problem in emptyvec(), it's in read_things() binding a temporary (the return value of emptyvec()) to a non-const reference parameter. –  Bwmat Jan 24 '13 at 22:25
    
It's certainly not perfectly fine when it tries to give a value vector to a mutable reference parameter. –  DeadMG Jan 27 '13 at 22:44
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.