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 *
- 它的数据类型不在我的控制范围内。
两个问题:
- 在这两种类型的上下文中,不兼容是什么意思?如果编译器被迫接受转换会发生什么?一个例子将不胜感激。
- 假设我必须使用
strcpy
,使上述代码行工作的安全方法是什么?
C++
严格检查 std::strcpy
期望 char*
的类型,而您的变量 var
是 unsigned char*
.
幸运的是,在这种情况下,像这样将指针转换为 char*
是完全安全的:
std::strcpy(reinterpret_cast<char*>(var), "string");
因为按照标准,char
、unsigned char
和signed 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 = #
编译器也会发出警告。因为它们是编译器中定义的不同类型。
所以,如果你写 'strcpy( (char*)var, "string")',代码只是将字符从 "string" 的 space 复制到 'var' 的 space。这里有没有bug就看你用'var'做什么了。因为 'var' 不是 'char *'
char
、signed char
和 unsigned 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 中的函数)。
以下代码行使用 HP-UX 的 C++ 编译器生成编译器警告:
strcpy(var, "string")
输出:
error #2167: argument of type "unsigned char *"
is incompatible with parameter of type "char *"
请注意:var
是这里的 unsigned char *
- 它的数据类型不在我的控制范围内。
两个问题:
- 在这两种类型的上下文中,不兼容是什么意思?如果编译器被迫接受转换会发生什么?一个例子将不胜感激。
- 假设我必须使用
strcpy
,使上述代码行工作的安全方法是什么?
C++
严格检查 std::strcpy
期望 char*
的类型,而您的变量 var
是 unsigned char*
.
幸运的是,在这种情况下,像这样将指针转换为 char*
是完全安全的:
std::strcpy(reinterpret_cast<char*>(var), "string");
因为按照标准,char
、unsigned char
和signed 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 = #
编译器也会发出警告。因为它们是编译器中定义的不同类型。
所以,如果你写 'strcpy( (char*)var, "string")',代码只是将字符从 "string" 的 space 复制到 'var' 的 space。这里有没有bug就看你用'var'做什么了。因为 'var' 不是 'char *'
char
、signed char
和 unsigned 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 中的函数)。