I am using C++ in native mode with Visual Studio 2017. That compiler compiles the statement below without complaint:
我正在使用c++的本机模式与Visual Studio 2017。该编译器毫无怨言地编译下面的语句:
const char * AnArrayOfStrings[] = {"z1y2x3w4", "Aname"};
However, if I change the above statement to specify that char is signed or unsigned, the compiler emits a C2440 error. For instance, the statements below, do not compile:
但是,如果我更改上面的语句来指定char是有符号的或无符号的,编译器会发出C2440错误。例如,下面的语句不编译:
const signed char * AnArrayOfStrings2[] = {"z1y2x3w4", "Aname"};
const unsigned char * AnArrayOfStrings2[] = {"z1y2x3w4", "Aname"};
I fail to see the reason for the compiler refusing to compile the statement when the sign of char is made explicit.
我不明白为什么编译器在char的符号被显式表示时拒绝编译语句。
My question is: is there a good reason that I have failed to see for the compiler refusing to compile those statements ?
我的问题是:我没有看到编译器拒绝编译这些语句的原因吗?
Thank you for your help (I did research in *, the C++ documentation, I used Google and, consulted about a dozen C/C++ books in an effort to find the answer myself but, a reason still eludes me.)
感谢您的帮助(我在*上做了研究,c++文档,使用了谷歌,查阅了十几本c++书籍,试图自己找到答案,但我还是找不到原因)。
2 个解决方案
#1
14
"z1y2x3w4"
is const char[9]
and there is no implicit conversion from const char*
to const signed char*
.
“z1y2x3w4”是const char[9],没有从const char*到const signed char*的隐式转换。
You could use reinterpret_cast
您可以使用reinterpret_cast
const signed char * AnArrayOfStrings[] = {reinterpret_cast<const signed char *>("z1y2x3w4"),
reinterpret_cast<const signed char *>("Aname")};
#2
3
If you compile the above code
如果您编译上述代码。
const signed char * AnArrayOfStrings2[] = {"z1y2x3w4", "Aname"};
in C with gcc using options -Wall
then it will give the following warning
在使用选项墙的C语言中,它将给出以下警告
test.c:5:49: warning: pointer targets in initialization differ in signedness [-Wpointer-sign]
const unsigned char * AnArrayOfStrings2[] = {"z1y2x3w4", "Aname"};
^
test.c:5:49: note: (near initialization for 'AnArrayOfStrings2[0]')
test.c:5:61: warning: pointer targets in initialization differ in signedness [-Wpointer-sign]
const unsigned char * AnArrayOfStrings2[] = {"z1y2x3w4", "Aname"};
The type of elements of AnArrayOfStrings2
and "z1y2x3w4"
are different. AnArrayOfStrings2[0]
is of type const signed char *
while "z1y2x3w4"
is of type const char[9]
.
The same code will raise error in C++. You will need explicit cast to make it work in C++.
AnArrayOfStrings2和z1y2x3w4元素类型不同。AnArrayOfStrings2[0]类型为const带符号char *,而“z1y2x3w4”类型为const char[9]。同样的代码会在c++中引起错误。您将需要显式转换才能使它在c++中工作。
To explain why
解释为什么
const char * AnArrayOfStrings[] = {"z1y2x3w4", "Aname"};
works I will take s simple example
我举个简单的例子
const char c[] = "asc";
const char *p1 = c; // OK
signed const char *p2 = c; // Error
unsigned const char *p3 = c; // Error
In the second line of the above snippet, c
will convert to const char *
thus making p1
and c
compatible types.
In third line the type of p2
and c
are incompatible and compiler will raise an error in C++ (a warning in C). Same will happen with line 4.
在上面代码片段的第二行,c将转换为const char *,从而使p1和c兼容类型。在第三行,p2和c的类型不兼容,编译器会在c++中产生错误(c中的警告)。
If we take another example for int
type
如果我们再举一个int类型的例子
const int i[] = {1,2,3};
const int *ii = i // OK
signed const int *si = i; // OK
unsigned const int *usi = i; // Error
First two pointer initializations work as int
without any specifier is equivalent to signed int
(but this is not true with char
) and therefore types are compatible. Intialization fails in last case as const int *
or signed const int *
is incompatible with unsigned const int *
.
前两个指针初始化的工作方式是不带任何说明符的int,相当于带符号的int(但是对于char来说不是这样),因此类型是兼容的。在最后一种情况下,由于const int *或有符号const int *与无符号const int *不相容,所以初始化失败。
#1
14
"z1y2x3w4"
is const char[9]
and there is no implicit conversion from const char*
to const signed char*
.
“z1y2x3w4”是const char[9],没有从const char*到const signed char*的隐式转换。
You could use reinterpret_cast
您可以使用reinterpret_cast
const signed char * AnArrayOfStrings[] = {reinterpret_cast<const signed char *>("z1y2x3w4"),
reinterpret_cast<const signed char *>("Aname")};
#2
3
If you compile the above code
如果您编译上述代码。
const signed char * AnArrayOfStrings2[] = {"z1y2x3w4", "Aname"};
in C with gcc using options -Wall
then it will give the following warning
在使用选项墙的C语言中,它将给出以下警告
test.c:5:49: warning: pointer targets in initialization differ in signedness [-Wpointer-sign]
const unsigned char * AnArrayOfStrings2[] = {"z1y2x3w4", "Aname"};
^
test.c:5:49: note: (near initialization for 'AnArrayOfStrings2[0]')
test.c:5:61: warning: pointer targets in initialization differ in signedness [-Wpointer-sign]
const unsigned char * AnArrayOfStrings2[] = {"z1y2x3w4", "Aname"};
The type of elements of AnArrayOfStrings2
and "z1y2x3w4"
are different. AnArrayOfStrings2[0]
is of type const signed char *
while "z1y2x3w4"
is of type const char[9]
.
The same code will raise error in C++. You will need explicit cast to make it work in C++.
AnArrayOfStrings2和z1y2x3w4元素类型不同。AnArrayOfStrings2[0]类型为const带符号char *,而“z1y2x3w4”类型为const char[9]。同样的代码会在c++中引起错误。您将需要显式转换才能使它在c++中工作。
To explain why
解释为什么
const char * AnArrayOfStrings[] = {"z1y2x3w4", "Aname"};
works I will take s simple example
我举个简单的例子
const char c[] = "asc";
const char *p1 = c; // OK
signed const char *p2 = c; // Error
unsigned const char *p3 = c; // Error
In the second line of the above snippet, c
will convert to const char *
thus making p1
and c
compatible types.
In third line the type of p2
and c
are incompatible and compiler will raise an error in C++ (a warning in C). Same will happen with line 4.
在上面代码片段的第二行,c将转换为const char *,从而使p1和c兼容类型。在第三行,p2和c的类型不兼容,编译器会在c++中产生错误(c中的警告)。
If we take another example for int
type
如果我们再举一个int类型的例子
const int i[] = {1,2,3};
const int *ii = i // OK
signed const int *si = i; // OK
unsigned const int *usi = i; // Error
First two pointer initializations work as int
without any specifier is equivalent to signed int
(but this is not true with char
) and therefore types are compatible. Intialization fails in last case as const int *
or signed const int *
is incompatible with unsigned const int *
.
前两个指针初始化的工作方式是不带任何说明符的int,相当于带符号的int(但是对于char来说不是这样),因此类型是兼容的。在最后一种情况下,由于const int *或有符号const int *与无符号const int *不相容,所以初始化失败。