Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7079263
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 28, 20262026-05-28T06:39:02+00:00 2026-05-28T06:39:02+00:00

In the example below, if we ignore the mutex for a second, copy elision

  • 0

In the example below, if we ignore the mutex for a second, copy elision may eliminate the two calls to the copy constructor.

user_type foo()
{
  unique_lock lock( global_mutex );
  return user_type(...);
}

user_type result = foo();

Now the rules for copy elision don’t mention threading, but I’m wondering whether it should actually happen across such boundaries. In the situation above, the final copy, in the logical abstract machine inter-thread happens after the mutex is released. If however the copies are omitted the result data structure is initialized within the mutex, thus it inter-thread happens before the mutex is released.

I have yet to think of a concrete example how copy elision could truly result in a race condition, but the interference in the memory sequence seems like it might be problem. Can anybody definitively say it can not cause a problem, or can somebody produce an example that can indeed break?


To ensure the answer doesn’t just address a special case, note that copy elision is (according to my reading) still allowed to occur if I have a statement like new (&result)( foo() ). That is, result does not need to be a stack object. user_type itself may also work with data shared between threads.


Answer: I’ve chosen the first answer as the most relevant discussion. Basically since the standard says elision can happen, the programmer just has to be careful when it happens across synchronization bounds. There is no indication of whether this is an intentional or accidental requirement. We’re still lacking in any example showing what could go wrong, so perhaps it isn’t an issue either way.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-28T06:39:02+00:00Added an answer on May 28, 2026 at 6:39 am

    Threads have nothing to do with it, but the order of constructors/destructors of the lock may affect you.

    Looking at the low level steps your code does, with out copy elision, one by one (using the GCC option -fno-elide-constructors):

    1. Construct lock.
    2. Construct the temporary user_type with (...) arguments.
    3. Copy-construct the temporary return value of the function, of type user_type using the value from step 2.
    4. Destroy the temporary from step 2.
    5. Destroy lock.
    6. Copy construct the user_type result using the value from step 3.
    7. Destroy the temporary from step 3.
    8. Later on, destroy result.

    Naturally, with the multiple copy elision optimizations, it will be just:

    1. Construct lock.
    2. Construct the result object directly with (...).
    3. Destroy lock.
    4. Later on, destroy result.

    Note that in both cases the user_type constructor with (...) is protected by the lock. Any other copy constructor or destructor call may not be protected.

    Afterthoughts:

    I think that the most likely place where it can cause problems is in the destructors. That is, if your original object, that constructed with (...) handles any shared resource differently than its copies, and does something in the destructor that needs the lock, then you have a problem.

    Naturally, that would mean that your object is badly design in the first place, as copies do not behave as the original object.

    Reference:

    In the C++11 draft, 12.8.31 (a similar wording without all the “moves” is in C++98:

    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. In such cases,
    the implementation treats the source and target of the omitted copy/move operation as simply two different
    ways of referring to the same object, and the destruction of that object occurs at the later of the times
    when the two objects would have been destroyed without the optimization. This elision of copy/move
    operations, called copy elision, is permitted in the following circumstances (which may be combined to
    eliminate multiple copies):

    • 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 cvunqualified
      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

    • a function or catch-clause parameter) whose scope does not extend beyond the end of the innermost
      enclosing try-block (if there is one), the copy/move operation from the operand to the exception
      object can be omitted by constructing the automatic object directly into the exception object

    • when a temporary class object that has not been bound to a reference would be copied/moved
      to a class object with the same cv-unqualified type, the copy/move operation can be omitted by
      constructing the temporary object directly into the target of the omitted copy/move

    • when the exception-declaration of an exception handler declares an object of the same type
      (except for cv-qualification) as the exception object, the copy/move operation can be omitted by treating the exception-declaration as an alias for the exception object if the meaning of the program
      will be unchanged except for the execution of constructors and destructors for the object declared by
      the exception-declaration.

    Points 1 and 3 collaborate in your example to elide all the copies.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

The example below throws an InvalidOperationException, Collection was modified; enumeration operation may not execute.
The example below, is just an example, I know that I don't need an
this example below works when hover event is trigered and when its not, its
In my example below I'm using a dijit.form.DateTextBox : <input type=text name=startDate dojoType=dijit.form.DateTextBox constraints={datePattern:'MM/dd/yyyy'}
In the example below I have a ListBox with dozens of font names in
In the .htaccess example below, if someone types in a URL like the following...
In the example below, if client code using GetPeople wanted to print the name
Given the example below, can someone please show me how this could be called?
The labels in the example below (WPF/XAML) just parade off the screen, no wrapping
Like in the example below, what is allowed, how and why? class Shape {

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.