简体   繁体   中英

!strcmp as substitute for ==

I'm working with rapidxml, so I would like to have comparisons like this in the code:

if ( searchNode->first_attribute("name")->value() == "foo" )

This gives the following warning:

comparison with string literal results in unspecified behaviour [-Waddress]

Is it a good idea to substitute it with:

if ( !strcmp(searchNode->first_attribute("name")->value() , "foo") )

Which gives no warning?

The latter looks ugly to me, but is there anything else?

You cannot in general use == to compare strings in C, since that only compares the address of the first character which is not what you want.

You must use strcmp() , but I would endorse this style:

if( strcmp(searchNode->first_attribute("name")->value(), "foo") == 0) {  }

rather than using ! , since that operator is a boolean operator and strcmp() 's return value is not boolean. I realize it works and is well-defined, I just consider it ugly and confused.

Of course you can wrap it:

#include <stdbool.h>

static bool first_attrib_name_is(const Node *node, const char *string)
{
    return strcmp(node->first_attribute("name")->value(), string) == 0;
}

then your code becomes the slightly more palatable:

if( first_attrib_name_is(searchNode, "foo") ) {  }

Note: I use the bool return type, which is standard from C99.

If the value() returns char* or const char* , you have little choice - strcmp or one of its length-limiting alternatives is what you need. If value() can be changed to return std::string , you could go back to using == .

When comparing char* types with "==" you just compare the pointers. Use the C++ string type if you want to do the comparison with "=="

You have a few options:

You can use strcmp , but I would recommend wrapping it. eg

bool equals(const char* a, const char* b) {
    return strcmp(a, b) == 0;
}

then you could write: if (equals(searchNode->first_attribute("name")->value(), "foo"))


You can convert the return value to a std::string and use the == operator

if (std::string(searchNode->first_attribute("name")->value()) == "foo")

That will introduce a string copy operation which, depending on context, may be undesirable.


You can use a string reference class. The purpose of a string reference class is to provide a string-like object which does not own the actual string contents. I've seen a few of these and it's simple enough to write your own, but since Boost has a string reference class, I'll use that for an example.

 #include <boost/utility/string_ref.hpp> using namespace boost; if (string_ref(searchNode->first_attribute("name")->value()) == string_ref("foo")) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM