Re: calling a function with a std::string argument using a null pointer

Discussion in 'C++' started by Kai-Uwe Bux, Jun 9, 2010.

  1. Kai-Uwe Bux

    Kai-Uwe Bux Guest

    Lynn McGuire wrote:

    > Does anyone know what happens when I call a function with a
    > std::string argument using a null pointer ? I have googled this
    > but have not gotten a good answer.

    [...]

    Undefined behavior: [21.3.1/9] governs the relevant constructor and requires
    that the pointer passed shall not be a null pointer. Hence, any program
    violating that constraint is in UB land.


    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Jun 9, 2010
    #1
    1. Advertising

  2. On 6/9/2010 10:50 AM, Lynn McGuire wrote:
    >>> Does anyone know what happens when I call a function with a
    >>> std::string argument using a null pointer ? I have googled this

    >>
    >> Undefined behavior: [21.3.1/9] governs the relevant constructor and
    >> requires
    >> that the pointer passed shall not be a null pointer. Hence, any program
    >> violating that constraint is in UB land.

    >
    > So this is functionally equivalent to "std::string aString = NULL" ?


    Mmm... Pretty much. Probably even to "std::string aString(NULL);"

    > Is there any way to modify this behavior of std::string other than
    > subclassing ?


    You cannot modify the behaviour of any standard component. You can only
    modify what *you* write.

    V
    --
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Jun 9, 2010
    #2
    1. Advertising

  3. Kai-Uwe Bux

    Jonathan Lee Guest

    Re: calling a function with a std::string argument using a nullpointer

    On Jun 9, 10:50 am, Lynn McGuire <> wrote:
    > Is there any way to modify this behavior of std::string other than
    > subclassing ?


    As Victor mentioned, you can't modify std::string. You
    could write an overload of someFunction():

    string someFunction(const char* p) {

    }
    Jonathan Lee, Jun 9, 2010
    #3
  4. Kai-Uwe Bux

    Jonathan Lee Guest

    Re: calling a function with a std::string argument using a nullpointer

    On Jun 9, 11:28 am, Jonathan Lee <> wrote:
    > As Victor mentioned, you can't modify std::string. You
    > could write an overload of someFunction():


    Arg.. sent by accident.

    string someFunction(const char* p) {
    return someFunction(string(p ? p : ""));
    }

    Hacky, but functional.

    --Jonathan
    Jonathan Lee, Jun 9, 2010
    #4
  5. Re: calling a function with a std::string argument using a nullpointer

    On 6/9/2010 11:30 AM, Jonathan Lee wrote:
    > On Jun 9, 11:28 am, Jonathan Lee<> wrote:
    >> As Victor mentioned, you can't modify std::string. You
    >> could write an overload of someFunction():

    >
    > Arg.. sent by accident.
    >
    > string someFunction(const char* p) {
    > return someFunction(string(p ? p : ""));
    > }
    >
    > Hacky, but functional.


    And considering the comment in the original post, perhaps it would be
    better to simply throw:

    std::string someFunction(std::string const& s) { .. normal .. }

    std::string someFunction(char const* ptr) {
    if (!ptr) throw("you forgot to initialize the pointer");
    return someFunction(std::string(ptr));
    }

    At least then, if passing NULL is really an error, it will be flagged,
    not masked...

    Just my $0.02.

    V
    --
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Jun 9, 2010
    #5
  6. Kai-Uwe Bux

    Jonathan Lee Guest

    Re: calling a function with a std::string argument using a nullpointer

    On Jun 9, 11:39 am, Victor Bazarov <> wrote:
    > And considering the comment in the original post, perhaps it would be
    > better to simply throw:


    Don't know if it's standard, but the constructor of std::string
    _does_ throw when null is passed in (for the computer I'm currently
    sitting at -- GCC 4.1.2). So why bother with a wrapper?

    --Jonathan
    Jonathan Lee, Jun 9, 2010
    #6
  7. Kai-Uwe Bux

    red floyd Guest

    Re: calling a function with a std::string argument using a nullpointer

    On Jun 9, 9:19 am, Lynn McGuire <> wrote:
    > >> So this is functionally equivalent to "std::string aString = NULL" ?

    >
    > > Mmm... Pretty much. Probably even to "std::string aString(NULL);"

    >
    > So, is it safe to say that "std::string aString = NULL" will have
    > a true comparison case of "aString.c_str () == NULL" ?
    >


    No. It's undefined behavior, which means *ANYTHING* can happen,
    including working "as-expected" (whatever "as-expected" means);
    segfaulting; causing errors elsewhere in your code; infecting your
    system with a virus (unlikely, but...)

    That's the whole point of undefined behavior. It's... undefined.
    red floyd, Jun 9, 2010
    #7
  8. Kai-Uwe Bux

    Kai-Uwe Bux Guest

    Jonathan Lee wrote:

    > On Jun 9, 11:39 am, Victor Bazarov <> wrote:
    >> And considering the comment in the original post, perhaps it would be
    >> better to simply throw:

    >
    > Don't know if it's standard, but the constructor of std::string
    > _does_ throw when null is passed in (for the computer I'm currently
    > sitting at -- GCC 4.1.2). So why bother with a wrapper?


    As far as I know, it's _not_ standard. The standard says it's undefined
    behavior. Hence, an implementation is free to crash, throw, or whatever it
    pleases.

    A wrapper would _ensure_ defined behavior.


    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Jun 9, 2010
    #8
  9. Kai-Uwe Bux

    Bo Persson Guest

    Lynn McGuire wrote:
    >>> So this is functionally equivalent to "std::string aString =
    >>> NULL" ?

    >>
    >> Mmm... Pretty much. Probably even to "std::string aString(NULL);"

    >
    > So, is it safe to say that "std::string aString = NULL" will have
    > a true comparison case of "aString.c_str () == NULL" ?
    >
    > Thanks,
    > Lynn McGuire


    No, not at all.

    It is highly likely that in this case the string constructor will call
    strlen(NULL) to try to size up the argument. This is very ungood.


    Bo Persson
    Bo Persson, Jun 9, 2010
    #9
  10. Kai-Uwe Bux

    Guest

    Re: calling a function with a std::string argument using a nullpointer

    On Jun 9, 1:20 pm, Lynn McGuire <> wrote:
    > > As far as I know, it's _not_ standard. The standard says it's undefined
    > > behavior. Hence, an implementation is free to crash, throw, or whatever it
    > > pleases.

    >
    > > A wrapper would _ensure_ defined behavior.

    >
    > Yes.  Our code would just require a LOT of wrappers.
    >
    > Thanks,
    > Lynn


    I think the "wrapper" that someone mentioned above was to create an
    overloaded function that takes a const char *. The function would do
    the null pointer check, adjust as necessary, and then forward the call
    to the real function taking a std::string.

    If you put that function in the same header as the original function,
    then your new function will be chosen over the old function for cases
    where it is invoked with a char *. Do you see why?

    So, only one "wrapper" (overloaded) function is needed in a single
    file and no changes to client code are needed.

    HTH
    , Jun 9, 2010
    #10
  11. Kai-Uwe Bux

    Guest

    Re: calling a function with a std::string argument using a nullpointer

    On Jun 9, 5:12 pm, Lynn McGuire <> wrote:
    > > I think the "wrapper" that someone mentioned above was to create an
    > > overloaded function that takes a const char *.  The function would do
    > > the null pointer check, adjust as necessary, and then forward the call
    > > to the real function taking a std::string.

    >
    > Got that.
    >
    > > If you put that function in the same header as the original function,
    > > then your new function will be chosen over the old function for cases
    > > where it is invoked with a char *.  Do you see why?

    >
    > Yes.
    >
    > > So, only one "wrapper" (overloaded) function is needed in a single
    > > file and no changes to client code are needed.

    >
    > What about the case where the function has two std::string arguments ?
    > Three wrappers will be required (NN, YN and NY).  Three ?  Seven
    > wrappers will be required (NYY, YYN, YYN, NNN, NNY, NYN, YNN).
    >


    If you are always passing char *, then no need for every combination.
    If you are mixing std:string and char * at the function call sites
    then yes you would have to
    make all of those overloads. But since you seem to imply that the
    code base is large, what is the alternative? You either make the
    wrappers or change all the call sites.

    > Wrappers are not a good solution for sophisticated programs.  Like
    > ours (600+ KLOC) with thousands of functions.
    >


    Are you equating sophistication with size?

    The wrapper solution is just a hack. A sophisitcated program does not
    call functions that take std::strings with pointers that can be null.
    The real issue is the use of pointers that can be null. But, hey, we
    all have to deal with legacy code. You have to decide the best way to
    fix things like this taking into account all of the other factors
    present in your development environment.
    , Jun 9, 2010
    #11
  12. Kai-Uwe Bux

    Öö Tiib Guest

    Re: calling a function with a std::string argument using a nullpointer

    On Jun 10, 12:12 am, Lynn McGuire <> wrote:
    >
    > What about the case where the function has two std::string arguments ?
    > Three wrappers will be required (NN, YN and NY).  Three ?  Seven
    > wrappers will be required (NYY, YYN, YYN, NNN, NNY, NYN, YNN).
    >
    > Wrappers are not a good solution for sophisticated programs.  Like
    > ours (600+ KLOC) with thousands of functions.


    Yes, you do not need such hacks like wrappers. Get rid of char
    pointers as acceptable types in your project. Replace these with real
    types like std::string, real POD structs or std::vector<char>. If the
    char* gets far from some external or legacy source of bytes then it is
    not C++ there.

    Sophisticated C++ program should not be so full of char* usage that
    possibility of these being null without anyone knowing from where they
    did come is a problem.
    Öö Tiib, Jun 10, 2010
    #12
  13. Kai-Uwe Bux

    Fred Zwarts Guest

    Re: calling a function with a std::string argument using a null pointer

    "Lynn McGuire" <> wrote in message
    news:
    >> I think the "wrapper" that someone mentioned above was to create an
    >> overloaded function that takes a const char *. The function would do
    >> the null pointer check, adjust as necessary, and then forward the
    >> call to the real function taking a std::string.

    >
    > Got that.
    >
    >> If you put that function in the same header as the original function,
    >> then your new function will be chosen over the old function for cases
    >> where it is invoked with a char *. Do you see why?

    >
    > Yes.
    >
    >> So, only one "wrapper" (overloaded) function is needed in a single
    >> file and no changes to client code are needed.

    >
    > What about the case where the function has two std::string arguments ?
    > Three wrappers will be required (NN, YN and NY).


    Why? Isn't one wrapper with two char * arguments sufficient?

    > Three ? Seven
    > wrappers will be required (NYY, YYN, YYN, NNN, NNY, NYN, YNN).


    Why seven? One wrapper function with three char * arguments would be sufficient.

    >
    > Wrappers are not a good solution for sophisticated programs. Like
    > ours (600+ KLOC) with thousands of functions.
    >
    > Thanks,
    > Lynn
    Fred Zwarts, Jun 10, 2010
    #13
  14. Kai-Uwe Bux

    Guest

    Re: calling a function with a std::string argument using a nullpointer

    On Jun 9, 7:16 pm, Lynn McGuire <> wrote:
    > > If you are always passing char *, then no need for every combination.
    > > If you are mixing std:string and char * at the function call sites
    > > then yes you would have to
    > > make all of those overloads.  But since you seem to imply that the
    > > code base is large, what is the alternative?  You either make the
    > > wrappers or change all the call sites.

    >
    > I'm changing all the call sites.  I totally suspect that I will
    > miss some calls and wait for the crashes in the testing phase to
    > show up.
    >
    > Thanks,
    > Lynn


    Probably a good choice. But, may I suggest you take it one step
    further.
    Instead of doing checks at each and every call site, why not change
    the functions that return the null pointers to not do so. That would
    seem to be the root cause of the issue. Or is that a larger change?

    If you have confidence in your regression tests, then you should be
    able to make changes w/o worrying about breaking stuff. Good luck.
    , Jun 10, 2010
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Vijai Kalyan
    Replies:
    4
    Views:
    690
    Vijai Kalyan
    Nov 8, 2005
  2. Fei Liu
    Replies:
    9
    Views:
    434
  3. Jeffrey Walton
    Replies:
    10
    Views:
    928
    Mathias Gaunard
    Nov 26, 2006
  4. aneuryzma
    Replies:
    3
    Views:
    692
    Jim Langston
    Jun 16, 2008
  5. Christopher
    Replies:
    4
    Views:
    428
    Ruben Safir
    Jul 9, 2011
Loading...

Share This Page