> It doesn't take a `T**` so it doesn't seem relevant to discussions of std::out_ptr though? You won't be able to use std::out_ptr with realloc so there's no chance of making a mistake with it. [...]
The problem is the same, it just happens to not take a T**. The problem is the same for any function that takes T**, I just couldn't think of one off the top of my head. I listed some below now. But also note that the absence of many APIs taking T** would also be an argument for these smart pointers not being so useful, so it's not really a counterargument!
> What function do you have that is both releasing resources and also doing other work which might fail?
See for example getdelim() or even asprintf(). asprintf() isn't guaranteed to return a valid pointer due to an error, so you can't free it unconditionally. getdelim() also isn't guaranteed to free the input if there is an I/O error, so you can't release that unconditionally either.
It would be helpful if you try to list some functions you believe you can use std::inout_ptr on.
I'm not sure what issue you're seeing with getdelim(). It never releases the underlying memory, AFAICT. You always need to call free at the end of the loop, regardless of whether there was a read error, a realloc failure, you hit EOF, or you broke out of the loop early. So why wouldn't the following be OK?
std::unique_ptr<char, free_deleter> line;
size_t len = 0;
while ((read = getdelim(std::inout_ptr(line), &len, delim, fp)) != -1) {
// ...
}
If the getdelim call ends up calling realloc and succeeding then we want to forget about the old pointer and not call `free` on it. We want to remember the new pointer and call `free` on that when we're done with the loop. That's what std::inout_ptr gets for us. It calls release() before the getdelim call and then calls reset() with the new value after the getdelim call.
If there is an I/O error or a realloc failure at some point in the file then `line` is left unmodified, pointing to the existing buffer. We still need to free that so keeping it under the control of the smart pointer is the right thing to do.
This seems like a perfect fit for std::inout_ptr.
The situation asprintf() is unfortunate. If it had been designed to set the out parameter to NULL on error or just to guarantee that it was unmodified on error then it would work with std::out_ptr. Unfortunately they decided that the out pointer would be instead be undefined on error so it is not safe to use with std::out_ptr.
The problem is the same, it just happens to not take a T**. The problem is the same for any function that takes T**, I just couldn't think of one off the top of my head. I listed some below now. But also note that the absence of many APIs taking T** would also be an argument for these smart pointers not being so useful, so it's not really a counterargument!
> What function do you have that is both releasing resources and also doing other work which might fail?
See for example getdelim() or even asprintf(). asprintf() isn't guaranteed to return a valid pointer due to an error, so you can't free it unconditionally. getdelim() also isn't guaranteed to free the input if there is an I/O error, so you can't release that unconditionally either.
It would be helpful if you try to list some functions you believe you can use std::inout_ptr on.