Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Const-correctness for non trivial variables

(kind of inspired by this answer although not related)

I've always been told (and been telling) that keeping const-correctness, even for short lived variables is valuable and good practice, e.g:

const std::string a = "Hello world";

Instead of

std::string a = "Hello world";

This:

  • Expresses intent more clearly.
  • Makes sure the variable is immutable so passing it to some function that might change it will make the compiler yell at you.
  • Might improve performance because of compiler optimizations.

Although ever since modern C++ introduced copy elision there have been a few clauses in the standard that allow the compiler to call the move constructor instead of the copy constructor:

In the following copy-initialization contexts, a move operation might be used instead of a copy operation:

(3.1) If the expression in a return statement ([stmt.return]) is a (possibly parenthesized) id-expression that names an object with automatic storage duration declared in the body or parameter-declaration-clause of the innermost enclosing function or lambda-expression, or

(3.2) if the operand of a throw-expression ([expr.throw]) is the name of a non-volatile automatic object (other than a function or catch-clause parameter) whose scope does not extend beyond the end of the innermost enclosing try-block (if there is one),

Does this mean there can actually be a performance penalty for using const objects with a non-default copy/move constructor instead of an increase when faced with situations this kind of elision would apply to?

like image 552
Hatted Rooster Avatar asked Oct 16 '22 05:10

Hatted Rooster


1 Answers

Does this mean there can actually be a performance penalty for using const objects with a non-default copy/move constructor

Potentially yes. When returning a local object, constness would prevent the use of a move construction that would have been allowed by the quoted rules. The performance penalty might not exist in practice though, because NRVO may still elide the entire copy/move whether the variable is const or not.

NRVO isn't guaranteed though, and not necessarily always possible - or simply not enabled (debug builds), so it may be worth it to use non-const when returning local variables by value.

like image 171
eerorika Avatar answered Oct 30 '22 14:10

eerorika