char* 和 unsigned char* 不兼容?

Incompatibility between char* and unsigned char*?

以下代码行使用 HP-UX 的 C++ 编译器生成编译器警告:

strcpy(var, "string")

输出:

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

请注意:var 是这里的 unsigned char * - 它的数据类型不在我的控制范围内。

两个问题:

  1. 在这两种类型的上下文中,不兼容是什么意思?如果编译器被迫接受转换会发生什么?一个例子将不胜感激。
  2. 假设我必须使用 strcpy,使上述代码行工作的安全方法是什么?

C++ 严格检查 std::strcpy 期望 char* 的类型,而您的变量 varunsigned char*.

幸运的是,在这种情况下,像这样将指针转换为 char* 是完全安全的:

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

因为按照标准,charunsigned charsigned char可以互为别名。

在 C 标准中,char 是实现定义的。 ANSI C 提供了三种字符类型(三种都占一个字节):char、signed char、unsigned char。不只是像short,int,只有两个。

你可以试试:

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

编译器会警告代码的第二行是error.It就像:

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

编译器也会发出警告。因为它们是编译器中定义的不同类型。

所以,如果你写 'strcpy( (char*)var, "string")',代码只是将字符从 "string" 的 space 复制到 'var' 的 space。这里有没有bug就看你用'var'做什么了。因为 'var' 不是 'char *'

charsigned charunsigned char 在 C++ 中是不同的类型。并且指向它们的指针是不兼容的——例如强制编译器将 unsigned char * 转换为 char * 以便将其传递给 strcpy() 正式导致未定义的行为——当指针随后被取消引用时——在几种情况下。因此警告。

与其使用 strcpy()(因此必须强制转换指针),不如使用(C++11 及更高版本)

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

没有未定义的行为。

更好的是,考虑使用标准容器,例如 std::vector<unsigned char>std::string,而不是使用原始数组。所有标准容器都提供了一种访问其数据的方法(例如,用于将合适的指针传递给遗留 API 中的函数)。