Understanding layout rules regarding C ++ 11

I tested the rvalue links and moved the semantics, and I want to make sure that I understand when to copy the copy, and when it should follow the semantics of movement.

Given the following

class NRVCA { public: NRVCA(int x): {} NRVCA(const NRVCA & Rhs) {} NRVCA& operator=(const NRVCA& dref) {} }; NVCRA GetATemp() { return NVCRA(5); } NVCRA GetACopy() { NVCRA ret(5); ... return ret; } int main() { //This call will be elided allays and invoke the single param constructor NVCRA A = GetATemp(); //This call will be a traditional copy the complier may elide this // if so the work will be done inline NVCRA B = GetACopy(); } 

In this case, the semantics of movement does not play any role, and the only difference from C ++ 03 in C ++ 11 is that instead of having the compiler resolved, they had to be eliminated.

So, Question 1. In what cases do I guarantee that the copy constructor will or will not be canceled.

Question 2. Is there a way to force the compiler not to be eliminated.

Question 3. Is there a logical reason why I would not want the compiler to do this, assuming that you have logically sequential copy operations.

Question 4. If I define a move constructor, the movement will occur in cases where the copy will not be moved anyway. Should this affect my class design.

+4
c ++ c ++ 11
Feb 13 2018-12-12T00:
source share
3 answers
  • Aliding copies and moves is always an optional optimization, and the standard makes no guarantees as to when this will be done. Elision differs from compiler selection over copy. The language ensures that when constructing a movement or assigning a movement, it is selected in accordance with its normal rules for resolving congestion.

  • Some compilers offer a flag to disable the exception. gcc and clang have -fno-elide-constructors . MSVC does not have a specific option, but disabling optimization may avoid some solutions (but some cannot be disabled no matter what, for example, a copy in Foo x = 1; )

  • I do not know a single reason not to copy / move in production assemblies.

  • Some people have recommended not relying on the "optimizaiton return value" when returning "heavy" classes, since RVO is not guaranteed. Personally, I just confirmed that my compilers were good at this and went ahead. Now that the objects can be moved, you no longer need to worry about whether the compiler supports this optimization, because even if it is not, you still get moves instead of copies.

+7
Feb 13 2018-12-12T00:
source share

Quote from the C ++ 11 standard (12.8 / 31): "When certain criteria are met, implementations are 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.", Like this:

  • Copying elision is not guaranteed. (technically, but compiler vendors are motivated that way for marketing reasons).
  • This is a compiler related issue.
  • Technically there are some cases ( see here ), but they will indicate (IMO) some design error.
  • You should still provide a move constructor (if you can implement it efficiently). There are cases when copying exceptions is prohibited, but moving the constructor is just fine:

     vector<string> reverse(vector<string> vec) { reverse( vec.begin(), vec.end() ); return vec; } auto vec = reverse(vector<string>{"abc", "def", "ghi"}); 

Copy elision is not explicitly permitted to propagate from a function argument to a finite automatic value initialized from a temporary. But no copy is called due to constructor movement.




To be more specific about my last comment, I quote N3290, which is hard to get at the moment, but it is very close to N3337 :

12.8 / 31:

When certain criteria are met, the implementation allows you to omit the copy / move construction of the object class, even if the copy / move constructor and / or object destructor have side effects. In such cases, the implementation considers the source and purpose of the missed copy / move operation as just two different ways of accessing the same object, and the destruction of this object occurs in later times when two objects would be destroyed without optimization. This permission to copy / move operations, called a copy, is allowed in the following circumstances (which can be combined with eliminate multiple copies):

- in the return statement in a function with a return type of the class, when the expression is a non-volatile automatic object name ( different from the function or catch-clause parameter ) with the same cv-unqualified type as the return type of the function, the copy / move operation can be omitted when building the automatic the object directly in the function returns the value

12.8 / 32:

When the criteria for excluding the copy operation are fulfilled or will be fulfilled, with the exception of the fact that the source object is a functional parameter and the object to be copied is denoted by lvalue, the overload resolution for selecting the constructor for the copy is first performed as if the object was denoted by rvalue. If the overload fails, or if the type of the first parameter of the selected constructor is not an rvalue reference to the type of the object (possibly with the qualification cv), overload resolution is performed again, considering the object as an lvalue. [...]

+4
Feb 13 '12 at 21:24
source share
  • I do not believe that there is any guarantee as to when the compiler can select a copy of the copy, even if the copy constructor has side effects. This is explicitly permitted by the standard.

  • Which compiler? For example, I believe that you can turn off optimization and not get elision in g ++. There is no way in the language to force any compiler to generate a copy constructor, where it considers elite to be possible. The standard explicitly allows elite, even when copy constructors have side effects.

  • I can’t think of a reason not to hide.

  • Copying elision should not affect the logical design of your class as a general rule. Create your class first, and then if you have performance issues, use the profiler to improve it.

+2
Feb 13 2018-12-12T00:
source share



All Articles