3 ms·
> So, if you do have a 1981 API it's completely incompatible with how you'd actually write C++ in 2021 is it though. I have plenty of .h in my /usr/include wit
by jcelerier 5y ago
> So, if you do have a 1981 API it's completely incompatible with how you'd actually write C++ in 2021
is it though. I have plenty of .h in my /usr/include with copyrights between 1980 and 1985. Sure, it's not modern best practices, but at least it's possible... and for a one-off task there's definitely not much point in doing a wrapper.
- tialaramex 5y agoYes. So, modern C++ says you want a unique_ptr to any owned resource you're not sharing, and otherwise a shared_ptr (or some equivalent smart pointer). Your 1981 API doesn't do that because those don't exist in 1981. Maybe it gives you a raw pointer to new resources. In 2021 those are just loose references which don't signify ownership, you need the wrapper to avoid this confusion leaking into your program. Maybe it gives you an integer handle which needs to be passed to some other API call to "release" the handle when you're done with it. Again you'll want a wrapper to handle this properly in your code or you may leak resources. You'll also want a wrapper because one integer is the same as another, but you probably shouldn't finished_with_cow(dog_number) or clean_up_dog(cow_number) even though those compile. Being forty years old it invariably won't be thread safe, so you'd also want to wrap it for that reason unless (as is often the case in C++) your code isn't thread safe anyway. "at least it's possible" isn't a differentiator. As I said you could also access this 40 year old API from Rust, but you'd want to build a wrapper for it because it the behaviour is so violently different from what's expected in the modern ecosystem.
- jcelerier 5y ago> Maybe it gives you a raw pointer to new resources. In 2021 those are just loose references which don't signify ownership, you need the wrapper to avoid this confusion leaking into your program. you can use unique_ptr directly for that. take for instance the 197x API, fopen: you can just do using file_handle = std::unique_ptr<FILE, decltype([] (FILE* file) { fclose(file); })>; and then store a file_handle in your class. > Maybe it gives you an integer handle which needs to be passed to some other API call to "release" the handle when you're done with it. Again you'll want a wrapper to handle this properly in your code or you may leak resources. You'll also want a wrapper because one integer is the same as another, but you probably shouldn't finished_with_cow(dog_number) or clean_up_dog(cow_number) even though those compile. it needs a one-time class to coax an int into behaving like a pointer but otherwise it's the same principle
- tialaramex 5y agoRight, you want to wrap this code, exactly like Rust. The point isn't that this is impossible it's that in both cases you want to write a wrapper to use them ergonomically in your modern software, C++ doesn't magically make 1980s code more respectful of object lifetime management than you'd think by reading Stroustrup's book at the time just because modern C++ (and the modern edition of the book) spends more time on this problem. I think Jason Turner put together a little example about this type of wrapping as the more sane way forward for people who've persuaded themselves they can't stomach a C++ ABI change because they have binaries with no source or their system is too complicated to re-test. Maybe as a C++ Weekly.
- jcelerier 5y ago> Right, you want to wrap this code, exactly like Rust In theory. In practice if it's a one-off task I'm definitely not going to bother and will just use the 1981 API directly, especially if it's used in a single file for instance. There's nothing I find more stupid than code style dogmatism - if it compiles it's kosher in the right circumstances.