Question: Original code

```
#include <iostream>
int global;
struct A
{
   A(){}
   A(const A&x){
       ++global;
   }
   ~A(){}
};
A foo()
{  
     A a;
     return a;  
}
int main()
{
   A x = foo();
   std::cout << global;
}

```

Output would be `0` on an optimized compiler supporting Named Return Value Optimization.

When I change the definition of `foo` to

```
A foo()
{ 
  { 
     A a;
     return a;  
  }
}

```

I get `1` as the output i.e copy c-tor gets called once. What could be the possible reason? Introducing a dummy scope changes the behavior of the code completely. What am I missing?

I tested it on g++ compiler. Any compiler guy around here who can explain the scenario in some implementation-specific manner?

**EDIT**

I tested it on clang and it optimizes the call to the copy c-tor even in the second case.

Andrew Pinski (gcc guy) confirmed that this is indeed a case of missed optimization on g++.

Answer: 
Theoretically you could get 1 in both situations. This is one of the situations when the compiler may or may not optimize the copy constructor away.

You can find more detailed information on the subject by googling for **"Return value optimization"** and **"Named return value optimization"**, in your case the latter.

Note if you change the code to:

```
A foo()
{ 
  { 
     return A();
  }
}

```

then the RVO should kick in and you'll obtain 0 on the output.

Why didn't NRVO kick in in the case you described? (I've confirmed this on GCC 4.6.) I'm not sure at this point; either the compiler isn't smart enough or there's a rule about NRVO which disallows it here.

---

Edit:

The standard says...

> 
> When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object, even if the copy/move constructor and/or destructor for the object have side effects. (...)
> This elision of copy/move operations, called copy elision, is permitted in the following circumstances:
> 
> 
> — in a return statement in a function with a class return type, when the expression is the name of a non-volatile automatic object (other than a function or catch-clause parameter) with the same cv-unqualiﬁed type as the function return type , the copy/move operation can be omitted by constructing
> the automatic object directly into the function’s return value
> 
> 
> 

Hence **it's permitted here, but the compiler wasn't smart enough to perform NRVO here.** If you work on GCC, you can check if it's the same on Clang and see if the result is different (my gut feeling says it will).

Note that RVO and NRVO are names for compiler features, while "copy elision" is how the standard refers to this behaviour in general.
That a compiler may miss some cases an optimization is possible even if it does it in other cases. AFAIK -- and I've checked now the place which allows the copy constructor elisions -- there is no constraint that the variable must be int the top scope in the function, it must just be an automatic variable.