Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In C++ - is it possible to compare volatile shared_ptr to nullptr?

It seems like the volatile comparison functions in shared_ptr implementation do not exist.

Does it even make sense to exist?

like image 979
Draif Kroneg Avatar asked Mar 31 '16 13:03

Draif Kroneg


2 Answers

Essentially no, the standard doesn't cater for comparisons or boolean conversion on a volatile shared_ptr.

The following fails to compile...

auto main() -> int {
    volatile shared_ptr<int> a;
    if (a == nullptr) // fails
        ; // empty
    if (a) // fails
        ; // empty
}

You could cast the volatile off (via. a const_cast), but I'm not sure that will have the desired outcome. From the cppreference:

Modifying a const object through a non-const access path and referring to a volatile object through a non-volatile glvalue result in undefined behavior.

In more general terms, in not marking member methods as volatile, the class or library implementors are effectively saying "this is not intended to be use as a volatile object" - if it were, then the appropriate methods or overloads would provide for volatile objects. Similarly, this applies to const, in marking members as const, they are saying "this class can be used as a const object.

Why is the volatile needed, what external sources could be modifying the shared_ptr "without the knowledge of the compiler" (this is one of the uses of volatile)? If there are threading issues, then you would be better served with one the thread library utilities, or if the requirement is simply turning off optimisations, various compilers have mechanisms for this already (pragmas etc.).

like image 99
Niall Avatar answered Sep 28 '22 08:09

Niall


Volatile is just an indication to the compiler that the memory may change unexpectedly. Turns off some optimizations. Under the covers its just a memory address.

The shared pointer is just holding/managing the resource. That said, since std::shared_ptr::get() isn't marked volatile, you cannot really use a shared_ptr to manage a volatile pointer in a accessible way.

I'd recommend using a naked pointer, and using scoped exit or the destructer to clean up after it.

If you are using volatile because the pointer may be modified by another thread, you may want to consider using std::atomic instead of volatile. In threading workflows, before std::atomic, pointers that were accessed from other threads were usually marked volatile. That is no longer best practice.

like image 29
Atifm Avatar answered Sep 28 '22 07:09

Atifm