1

I have a function like this:

void Test(std::wstring test1) { cout << test1.c_str(); } 

When I call it like this:

Test(NULL); 

I get runtime exceptions like "invalid handle" and the entire program crashes. I can't do a null check on parameter 'test1' because the compiler says it can't be null. I'd like to either prevent a NULL from being passed in the first place, or have a way to check for NULLs at runtime. How can I solve this problem?

10
  • Compile your code with proper flags, I think it should work with a warning. No ? Commented Jul 18, 2013 at 21:06
  • 3
    Ummm... don't pass NULL? Commented Jul 18, 2013 at 21:09
  • 1
    @JonTackabury, If you're moving to std::wstring, it should fix itself when you change the callsites to use std::wstring. If those are in user's programs, then an overload would probably be the best solution for them not to change their code, but you can at least change the code you manage to call it correctly. Commented Jul 18, 2013 at 21:14
  • 2
    @JonTackabury Changing the parameter type from LPWSTR to std::wstring changes the interface, as you've discovered. You either have to update the client code to adhere to the new interface or you have to do something to maintain the old interface (e.g., by adding an overload that works with NULL). Commented Jul 18, 2013 at 21:22
  • 1
    What do you expect Test(NULL) to do? I think you may be confusing a null pointer with an empty string. They are not the same thing though some other strings classes might treat a null pointer as a special case and construct and empty string. You probably just want Test(L""); Commented Jul 18, 2013 at 23:00

2 Answers 2

7

Unfortunately in this case you just have to write correct code: The null pointer is implicitly convertable to wstring (through the C-string constructor) and that constructor requires the C-string pointer to be non-null.

You have to do the null check prior to calling Test. You could implement an overload to help with this though:

void Test(const wchar_t* test1) { if(test1) Test(std::wstring(test1)); } 

Note that this may hide problems and you may want to assert in the overloaded Test function and/or simply fix the calling code so it never passes in an invalid string in the first place.

Sign up to request clarification or add additional context in comments.

2 Comments

Doing a null check before calling the function, or creating overloads seems like the best (and only) real options. Thanks for the help!
Damn, it's always unfortunate when one has to write correct code :D
1

The specification for std::wstring says that you must not pass NULL to wstring's constructor. Doing so results in undefined behavior.

To avoid this you can overload your Test function such that passing NULL calls an overload that doesn't try to construct wstring from NULL.

void Test(wchar_t const *test1) { if (test1) std::wcout << test1; } void Test(std::wstring const &test1) // added const & to avoid unnecessary copies { Test(test1.data()); } 

Now Test(NULL) will call the wchar_t const * overload and NULL will never be passed to the std::wstring constructor.

3 Comments

I'll give you that you can overload it for the easiest solution to integrate with the existing code, but you can output the string directly, and should use std::wcout to do that.
@chris well one should avoid duplicate implementations. Although I show implementing the new overload in terms of the OP's code I grant that it would probably be better to refactor and flip that around.
I already UVed :) This was the first to suggest overloading, and the output wasn't relevant to the actual answer, so it didn't influence my decision.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.