From: Edward Diener (eldiener_at_[hidden])
Date: 2019-12-03 22:48:24


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.