How to handle NULL string for UTF conversion function

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

How to handle NULL string for UTF conversion function

Boost - Dev mailing list
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
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);`
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)
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.

Thanks for reading and any insight is welcome!

Alex




_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

smime.p7s (6K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: How to handle NULL string for UTF conversion function

Boost - Dev mailing list
On Tue, Dec 3, 2019 at 4:06 PM Alexander Grund via Boost
<[hidden email]> 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

I think if input is nullptr than output can be nullptr as well.

Artyom

> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: How to handle NULL string for UTF conversion function

Boost - Dev mailing list
On 4/12/2019 09:50, Artyom Beilis wrote:
> I think if input is nullptr than output can be nullptr as well.

Mostly this, when both sides are pointers.

If one is a string type, so that you can't represent nullptr, then
there's a couple of choices:

1. Use optional<string> so that you can explicitly represent the null
state.  This also acts as a hint to the user that the method has some
special handling for the null case.

2. Treat an empty string as equivalent to nullptr.  This would usually
be safe (an empty filename is usually illegal, although an empty
directory name is not).

Either way will probably require conditional logic to bypass the normal
conversion.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: How to handle NULL string for UTF conversion function

Boost - Dev mailing list
In reply to this post by Boost - Dev mailing list
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.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: How to handle NULL string for UTF conversion function

Boost - Dev mailing list
In reply to this post by Boost - Dev mailing list
> 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);`

or with some kind of gsl::not_null would be even better?
int fFOO(gsl::not_null<const char*> s);

But I do not think boost has gsl.

Frédéric

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: How to handle NULL string for UTF conversion function

Boost - Dev mailing list
In reply to this post by Boost - Dev mailing list
Alexander Grund 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().

This. Since (w)stackstring is an internal utility class, we should make it
behave in whatever way is most useful for the implementation, and in this
case, NULL-in-NULL-out is correct.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost