Why is std::weak_ptr::expired optimized away?

前端 未结 1 473
清酒与你
清酒与你 2021-02-03 20:32

In the following code, while ( !Ref.expired() ); is joyfully optimized into an infinite loop. If the line of code is changed to while ( !Ref.lock() );.

相关标签:
1条回答
  • 2021-02-03 21:21

    Your program is incorrect; the shared-ownership pointer facilities are not intended to be used for synchronization.

    [intro.multithread]/24:

    The implementation may assume that any thread will eventually do one of the following:
    — terminate,
    — make a call to a library I/O function,
    — access or modify a volatile object, or
    — perform a synchronization operation or an atomic operation.

    std::weak_ptr::expired() is not a synchronization operation or an atomic operation; all the Standard says is that it does not introduce a data race. Since the resolution to Library defect 2316, std::weak_ptr::lock() is considered an atomic operation, so to answer 2) your code using Ref.lock() is valid as of C++14.

    Now, it's true that if you were to attempt to create your own library implementation of weak_ptr using the language and library facilities, it would necessarily use the synchronization and/or atomic operation facilities, so a user-provided weak_ptr::expired() would be OK to spin on (the implementation would be obliged to ensure that the thread eventually made progress, per [intro.multithread]/2 and /25). But an implementation is not obliged to restrict its own library to the language and library facilities.

    I'm not entirely sure how the compiler is optimizing away the access to expired(). I'd guess that the MSVC library is exploiting aspects of the x86 memory model that the compiler/optimizer observes are not guaranteed by the C++ memory model.

    0 讨论(0)
提交回复
热议问题