Why is strcmp unknown to clang?

Barth picture Barth · Jun 21, 2012 · Viewed 9.7k times · Source

I have a basic program that compares two strings :

#include <string>
#include <iostream>

using namespace std;

int main (int argc, char *argv[]) {
  if(strcmp (argv[0],"./test") != 0) {
    cout << "not equal" << endl;
  } else {
    cout << "equal" << endl;
  }
  return 0;
}

it compiles with gcc but not with clang :

 > clang -o test test_clang.cpp 
test_clang.cpp:7:6: error: use of undeclared identifier 'strcmp'
  if(strcmp (argv[0],"./test") != 0) {
     ^
1 error generated.

Why doesn't it compile with clang ?

EDIT: People are getting harsh on stack overflow, up to the point that I am hesitating to post a question. The question above has a simple answer, fine, but is it normal to down-vote questions (twice in the first minute!) because they have a simple, yet non obvious, answer ?

Answer

Tomas Andrle picture Tomas Andrle · Jun 21, 2012

Use

#include <string.h>

or

#include <cstring>

instead of

#include <string>

The string header is for the std::string from C++. string.h is for C zero terminated char* strings. cstring is like string.h but for C++.

The reason it worked with gcc is probably different warning/error level settings. It is possible to compile the code without #including the header and having the declaration of strcmp. The compiler will not be able to do type checking but the symbol still gets resolved by the linker.

You can also avoid using strcmp completely and write

#include <string>
#include <iostream>

int main (int argc, char *argv[]) {
  std::string command = argv[0];

  if( command != "./test" ) {
    std::cout << "not equal" << endl;
  } else {
    std::cout << "equal" << endl;
  }
  return 0;
}

Using a std::string on one side of the comparison will cause the "./test" string to be converted into a std::string as well and the comparison will be done by the == operator of the std::string class.