4 ms·
I would say that calling these "C APIs" is a bit misleading, as they have to call `new` for these helper types to be useful. I would call these legacy C++ APIs,
by planede 4y ago
I would say that calling these "C APIs" is a bit misleading, as they have to call `new` for these helper types to be useful. I would call these legacy C++ APIs, although I have recently seen new APIs written with this horribly awful `void foo(T* out_param_for_owning_ptr)` interface.
Interfacing with these with a smart pointer without a helper type is kind of inconvenient, since then you need to do something like:
T* raw_owning_ptr;
foo(&raw_owning_ptr);
std::unique_ptr<T> ptr(raw_owning_ptr);
`out_ptr` and friends are a bit niche, just for interfacing with these kinds of APIs.
- linkdd 4y agoWhy would you have to call `new`? Why would `malloc()` not work here?
- leeter 4y agoIt would; you'd just have to supply a custom "free_deleter" in the definition of the unique_ptr that calls free instead of delete. I've used this for Windows System calls like GetAddrInfoExW which requires calling FreeAddrInfoEx when you're done. std::unique_ptr<ADDRINFOEXW, addrinfo_deleter> holder; ADDRINFOEXW hint = { .ai_family = AF_UNSPEC }; if (const auto result = GetAddrInfoExW( sHost , nullptr , NS_ALL , nullptr , &hint , std::out_ptr(holder) , nullptr , nullptr , nullptr , nullptr); result != ERROR_SUCCESS) { // print error here }
- linkdd 4y agoThis seems reasonable for working with C APIs.
- kllrnohj 4y agoOr globally replace the new and delete operators to call malloc & free, as they commonly already do such as in libstd++ and libc++ But having malloc/free cross a library boundary (that is library A malloc and wants the caller in a different library to call free) is also a code smell in general and potentially very problematic. So you'll be generally doing custom deleters regardless
- planede 4y agoAh, right, so `out_ptr` works with any unique_ptr and shared_ptr, doesn't have to hold the `default_deleter`. `default_deleter` would call `delete` down the line, which does not match up with `malloc`.
- leeter 4y agoCorrect, the main value of std::out_ptr is the exception safety. There is no gap between the call and when you wrap the value in a smart pointer where something can happen and cause a leak. Is it strictly necessary in all cases? No, but it's a nice to have because it makes code less error prone if there are multiple paths. You can ensure the resource will be released when the scope ends. A code reviewer could look at the deleter to ensure it was the correct one for the use and be satisfied in most cases.