Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

Is there a difference between this:

MyClass c = getMyClass();
calculate(c.value);

and this:

calculate(getMyClass().value);

in the scope of performance and memory allocation?

share|improve this question

migrated from programmers.stackexchange.com Jun 27 at 4:29

This question came from our site for professional programmers interested in conceptual questions about software development.

2  
There might actually be a semantic difference, for example if getMyClass returns a reference the first invokes the copy constructor (RVO non withstanding) but the latter doesn't. –  delnan Jun 24 at 6:19
3  
Is "easier to display the intermediate value in some debuggers" a significant difference for you? –  Doc Brown Jun 24 at 9:57
    
Well, what i meant was what were the effects on performance and memory allocation ? –  Semih Kekül Jun 24 at 10:08
    
@Semih Kekül the first example uses value(), while the second example uses value. –  Jace Browning Jun 24 at 15:26
    
@JaceBrowning thanks, I have edited. –  Semih Kekül Jun 24 at 15:28

4 Answers 4

Yes, there is a fairly serious difference. In the first case, c is an lvalue, and it will not be destroyed until the end of the scope. This can delay useful things like reosurce cleanup. More problematically, it being an lvalue means that it cannot be moved, but must be copied, which is inefficient for many classes but downright illegal for some very important classes, like unique_ptr.

In the second case, the compiler cleans up the temporary right away, so all resources are released promptly, and it being an rvalue gives the compiler more freedom to optimize and permits move semantics.

This is still true when value is a member or member function, as the result of both can inherit value category from their parent object.

You should always scope objects to the minimum scope required, and if you don't need to access c later, then you should use the temporary.

share|improve this answer
    
If getMyClass() returns const MyClass& and MyClass::value() is a const function (which may or may not be true based on the original question), can the compiler optimize the MyClass c = code so that no instance of MyClass is created? If so, does it make sense to say c will not be destroyed until the end of the scope? I'm trying to understand the text above in light of comments made elsewhere. –  David K Jun 25 at 13:09

Is there a difference? Yes, massively so. To the reader.

The compiler couldn't care less which way you write it. The code emitted, space used and time of execution are so close they're not worth spending one millisecond of thinking time on.

But your readers will care. In some situations the first form offers the opportunity to provide a useful variable name to help explain your intent. In other situations the lack of a declared variable makes it a single statement and could be easier to read, especially if there are lots of them.

Please, get over the idea you should care about what the compiler thinks and start to care more about what your readers think! And, by the way, you are one of those readers in six month's time.

share|improve this answer
4  
The compiler absolutely does care which way you write it. –  Puppy Jun 24 at 10:26

Nope! It merely evaluates the getMyClass().value expression and sends it to the method's parameter. Of course, the parameter itself is a local variable scoped to the method.

share|improve this answer
1  
Which will certainly be deleted in a non-debug compilation. –  david.pfx Jun 24 at 10:20
    
His unedited question was about whether some phantom local variable would be temporarily created for the expression at the 2nd option: calculate(getMyClass().value);. He wasn't concerned if it's deleted later! –  GoToLoop Jun 24 at 18:17
    
Much less asked for scolding him for worrying about performance as you did @david.pfx! –  GoToLoop Jun 24 at 18:28

The first form tells the compiler to create a new instance of MyClass. If getMyClass() returns a const reference to MyClass, you don't really need a new instance. Your compiler may optimize the new instance away, but under those circumstances, if MyClass::value() is a const function, I prefer to write

const MyClass& c = getMyClass();
calculate(c.value());

Even if getMyClass() returns a simple MyClass, technically you can still declare const MyClass& c; the compiler will simply force the new instance of MyClass to remain in existence as long as c is in scope, similar to what happens if you declare MyClass c, though there are arguments over whether this is a good coding practice (see here or here).

As has already been pointed out, the instance created by the first form continues to exist until the end of the scope, although you can minimize the effect in this case by adding an extra pair of { and }:

{
  MyClass c = getMyClass();
  calculate(c.value());
}

Personally, in most cases I prefer to create a local variable with a name that tells me something about what I'm passing to the calculate function, to make the code more self-documenting. An exception is when I have to call calculate several times in a row on different values, in which case it may be clearer what's happening if the calls occur on consecutive lines of code without declaring any new variables.

share|improve this answer
1  
"the first form forces the construction of an additional instance of MyClass" It most assuredly does not. Eliminating such trivialities are well within the compiler's power. –  Puppy Jun 25 at 12:00
    
Given the much more surprising things compiler optimization can do, I should have thought of that. I've removed the word "forces" and changed this to a style preference. Of is there a reason to write MyClass c = instead of const MyClass& c = when getMyClass returns const MyClass&? –  David K Jun 25 at 12:22
    
By the way, regarding the consequences of the "c is an lvalue" objection, are those all things the compiler can't fix, at least in the case where getMyClass returns const MyClass&? Because that objection was what made me think of the const MyClass& c thing in the first place. –  David K Jun 25 at 12:28
    
If you want to mutate c? If the object referenced by getMyClass may be deleted soon? Besides, there is no guarantee that getMYclass does, infact, return const MyClass&. And yes, those are things the compiler absolutely cannot fix. It is a user-observable semantic, not an implementation detail. –  Puppy Jun 25 at 12:29
    
Based on the original question, we don't know what getMyClass() returns, but in an actual programming environment you can usually find that out. As for mutating c--oops, I assumed MyClass::value() is a const function, which wasn't given. OK, made note of that too in the answer. But other than that, OP indicates no desire to mutate c. And if the value behind getMyClass() is so likely to disappear or mutate under us, I don't know if I even trust the results of calculate(getMyClass().value). That seems a rather different question. –  David K Jun 25 at 13:00

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.