PeterSommerlad / SC22WG21_Papers

My submissions to SC22WG21 C++ ISO/IEC standardization group
43 stars 13 forks source link

Should unique_resource::reset() clear the holded resource ? #18

Closed svart-riddare closed 10 months ago

svart-riddare commented 10 months ago

Using std::experimental::unique_resource, I stumbled upon an unexpected behavior of the reset() function that I can mostly state as reset() does not reset the owned resource.

Building upon one of your code sample:

void demonstrate_unique_resource_with_stdio() {
    const std::string filename = "hello.txt";
    auto fclose=[](auto fptr){::fclose(fptr);};
    {
        auto file = unique_resource(::fopen(filename.c_str(), "w"), fclose);
        ::fputs("Hello World!\n", file.get());
        ASSERT(file.get() != NULL);
    }

    // Let's reset the resource
    file.reset();

    // unique_resource::reset() has been called, but get() returns resource as before
    ASSERT(file.get() != NULL);  

    // however, resource is no longer usable, the following may crash
    ::fputs("Crash?", file.get());
}

Once reset() has been called, there is no way to know the state of the resource, as there is no operator! (or is_valid()) member function for example.

I would have exepected to be able to retrieve this information, either because reset() would have restored the resource to it's default value (i.e. RESOURCE = {} when possible) either by having a member function to check whether the return value of get() is valid or not.

PeterSommerlad commented 10 months ago

To achieve the expected outcome you need to use reset(NULL) or use unique_ptr for FILE*

There is more generic "empty" state that ist used.

However, I abandoned generic unique_resource and scope guards, in favor of recommending a per resource implementation of a manager class providing a better abstraction.

See my talks "What Classes we design and how"

svart-riddare commented 10 months ago

Thank you for your quick answer, the example I gave was only to support my comment about the fact that once reset() has been called at least once, we are unable to know whether the object contains somethig valid or not.

As I understand from your comment and the corresponding sequence in your talk, std::experimental::unique_resource may never make it to the std namespace, so I will stop using it.