On 12/3/2019 9:06 AM, Alexander Grund via Boost wrote:
Hi,
in my work on Boost.Nowide I encountered a valid NULL string and am unsure how to handle it.
Context: Every wrapper functions is basically implemented like: int fFOO(const char* s){ wstackstring const ws(s); // Converts UTF-8 to wchar-buffer/string return _wfFoo(ws.c_str()); }
Similar functions like `std::wstring widen(string-or-const-char-ptr)` are provided which can be used like `return _wfFoo(widen(s).c_str());` in the example above.
All was fine, because (IIRC) calling e.g. `fopen(NULL)` is not allowed anyway.
However `freopen` DOES allow a NULL for the string. So now I'm left with a couple options and would like some opinions on them:
1. Make (w)stackstring aware of NULL input and if default constructed or with NULL return NULL for c_str(). Makes it easy to use as one could even say `return _wfFoo(wstackstring(s).c_str());` w/o any checks but would be inconsistent with the `widen` functions which convert the passed pointer into a std::(w)string and hence require != NULL
Never return NULL from c_str(), as opposed to a C pointer to an empty C string. Nobody else has ever done this, no one will expect it, and it will just confuse users who deal with other string objects which have a c_str() function.
2. Disallow NULL (via assert) for all conversions and require manual checking. Best usage would then probably be to ditch the temporary and do `return _wfFoo(s ? wstackstring(s).c_str() : NULL);`
Sounds best. It's C++ and NULL is C. Forget about C. The library I take it will soon be in Boost and be for C++ users.
3. Just like 1. but rename (w)stackstring to e.g. (w)cstring (or ncstring/wcstring, or narrow_cstring/wide_cstring) to highlight that it acts like a C-String (and can be NULL as opposed to empty but never NULL)
Waste of time. No matter what it is called returning NULL as opposed an empty string from c_str() is just wrong.
4. Ditch stackstring entirely. It was complained about by Zach during the review although defended by the author as "stackstring is barely on-stack buffer optimization - it isn't general string and never intended to be so. It isn't in details because it can actually be useful outside library scope." So this would worsen performance a bit as usual SSO are to small for common filenames.
You are going to need some string object, unless the library is strictly for C users <g>, so ditching stackstring does not seem like a solution.
Thanks for reading and any insight is welcome!
The gist is, with all respect to Stroustrup, that the time has been long past when C++ should worry about C-isms, or bend library design to accomodate C programmers. Any C++ programmer who actually wants to use 'freopen' and pass NULL, can manually check their string object for an empty string and pass NULL to 'freopen' is that is the case.