const char* to bool, not std::string(bug) - Journal of CTar - GameDev.net

const char* to bool, not std::string(bug)

posted in Journal of CTar
Published November 23, 2005
Advertisement
I found a very strange bug in some of my code the other day, I isolated the problem to this:

#include #include void Print(bool P){	std::cout << P;}void Print(const std::string& P){	std::cout << P;}int main(){	Print("test\n");	const std::string Tmp = "test\n";	Print(Tmp);	return 0;}


What do you think this will output? I thought the output would be:
testtest


But the output (in both VC7.1 and VC8.0) is:

1test


In VS2005 the code compiles without a single error on the highest warning level (4). I did some debugging and figured out the bool overload was called with the first function call, and the std::string overload was called with the second function call. First when I tried to code in VS2003 I found the error, I got the warning:
\Main.cpp(15) : warning C4800: 'const char *' : forcing value to bool 'true' or 'false' (performance warning)

Then it quickly became clear that I was passing a const char*, I thought it would be converted to a std::string, but since a const char* is just a pointer it was converted to a boolean, true in this case because the address wasn't 0.

I fixed it by adding an overload taking const char*. So this is what happens when you think of const char* as a string, not a pointer and when you assume "test" is more likely to be converted to a string than a boolean value.
0 likes 2 comments

Comments

ApochPiQ
I've been nailed by that one before. In general, I've started using const char* parameters everywhere where I don't actually need an explicit string, and/or using string("string literal") to ensure that a string is always constructed from a literal when needed.

The alternative (which is useful for a different class of problems) is to store all string literals in a centralized area, like a string table resource or a header file. Then define a unified interface to accessing them, and use that instead of inlined hardcode strings. I started doing that mainly for localization purposes, but it proves handy in other areas as well.
November 23, 2005 05:32 PM
CTar
Quote:
The alternative (which is useful for a different class of problems) is to store all string literals in a centralized area, like a string table resource or a header file. Then define a unified interface to accessing them, and use that instead of inlined hardcode strings. I started doing that mainly for localization purposes, but it proves handy in other areas as well.


As you say yourself there is also problems with this, others though. You could make the class look up the string with a recieved char* or you could look up the string yourself and send the string to whatever class needs it.

One problem with letting the class look up the string itself can be that the users of my library probably wont use a string table, and even if they do they probably wont use my approach.

A problem with letting the user of the class look up the string itself could be that when they dont want to look up the string they can't just pass a string literal.

So I would say the best solution would be too let the user pass a char* or a string and let the looking up strings be the user's resposibility, but your application might have other needs, but for a general purpose library I think this is the best approach (others I haven't heard of may exist).
November 24, 2005 07:11 AM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement
Advertisement