为什么c++不接受字符数组的带符号或无符号字符

时间:2022-05-31 21:22:26

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 *不相容,所以初始化失败。