Hassaan
Hassaan

Reputation: 253

Incompatibility between char* and unsigned char*?

The following line of code produces a compiler warning with HP-UX's C++ compiler:

strcpy(var, "string")

Output:

error #2167: argument of type "unsigned char *" 
    is incompatible with parameter of type "char *"

Please note: var is the unsigned char * here - its data type is outside of my control.

Two questions:

  1. What does incompatibility mean in the context of these two types? What would happen if the compiler was forced to accept the conversion? An example would be appreciated.
  2. What would be a safe way to make the above line of code work, assuming I have to use strcpy?

Upvotes: 5

Views: 3200

Answers (3)

Galik
Galik

Reputation: 48615

C++ is being strict in checking the types where std::strcpy expects a char* and your variable var is an unsigned char*.

Fortunately, in this case, it is perfectly safe to cast the pointer to a char* like this:

std::strcpy(reinterpret_cast<char*>(var), "string");

That is because, according to the standard, char, unsigned char and signed char can each alias one another.

Upvotes: 4

Peter
Peter

Reputation: 36597

char, signed char, and unsigned char are distinct types in C++. And pointers to them are incompatible - for example forcing a compiler to convert a unsigned char * to char * in order to pass it to strcpy() formally results in undefined behaviour - when the pointer is subsequently dereferenced - in several cases. Hence the warning.

Rather than using strcpy() (and therefore having to force conversions of pointers) you would be better off doing (C++11 and later)

const char thing[] = "string";
std::copy(std::begin(thing), std::end(thing), var);

which does not have undefined behaviour.

Even better, consider using standard containers, such as a std::vector<unsigned char> and a std::string, rather than working with raw arrays. All standard containers provide a means of accessing their data (e.g. for passing a suitable pointer to a function in a legacy API).

Upvotes: 1

Gleipnir
Gleipnir

Reputation: 36

In C Standard, the char is Impementation Defined. ANSI C provides three kinds of character types(All three take one byte): char, signed char, unsigned char. Not just like short, int, only two.

You can try:

char *str="abcd"; signed char *s_str = str;

The compiler will warn the second line of the code is error.It just like:

short num = 10; unsigned short *p_num = &num;

The compiler will warn too. Because they are different type defined in compiler.

So, if you write 'strcpy( (char*)var, "string")',the code just copy the characters from "string"'s space to 'var's space. Whether there is a bug here depends on what do you do with 'var'. Because 'var' is not a 'char *'

Upvotes: 1

Related Questions