c++ - resueltos - imprimir cadena de caracteres en c
¿Por qué C++ no acepta caracteres firmados o sin firmar para matrices de caracteres? (2)
Estoy usando C ++ en modo nativo con Visual Studio 2017. Ese compilador compila la siguiente declaración sin queja:
const char * AnArrayOfStrings[] = {"z1y2x3w4", "Aname"};
Sin embargo, si cambio la declaración anterior para especificar que char está firmado o sin firmar, el compilador emite un error C2440 . Por ejemplo, las declaraciones a continuación, no compilan:
const signed char * AnArrayOfStrings2[] = {"z1y2x3w4", "Aname"};
const unsigned char * AnArrayOfStrings2[] = {"z1y2x3w4", "Aname"};
No veo la razón por la que el compilador se niega a compilar la declaración cuando el signo de char se hace explícito.
Mi pregunta es: ¿hay una buena razón por la que no he podido ver si el compilador se niega a compilar esas declaraciones?
Gracias por su ayuda (hice una investigación en StackOverflow, la documentación de C ++, utilicé Google y consulté una docena de libros de C / C ++ en un esfuerzo por encontrar la respuesta por mi cuenta, pero aún no se me aclara una razón).
Si compilas el código anterior
const signed char * AnArrayOfStrings2[] = {"z1y2x3w4", "Aname"};
en C con gcc usando las opciones -Wall
entonces dará la siguiente advertencia
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"};
El tipo de elementos de AnArrayOfStrings2
y "z1y2x3w4"
son diferentes. AnArrayOfStrings2[0]
es de tipo const signed char *
mientras que "z1y2x3w4"
es de tipo const char[9]
.
El mismo código generará error en C ++. Necesitará una conversión explícita para que funcione en C ++.
Para explicar por que
const char * AnArrayOfStrings[] = {"z1y2x3w4", "Aname"};
obras voy a tomar s ejemplo simple
const char c[] = "asc";
const char *p1 = c; // OK
signed const char *p2 = c; // Error
unsigned const char *p3 = c; // Error
En la segunda línea del fragmento de código anterior, c
se convertirá en const char *
lo que hace que los tipos p1
c
compatibles.
En la tercera línea, el tipo de p2
c
son incompatibles y el compilador generará un error en C ++ (una advertencia en C). Lo mismo ocurrirá con la línea 4.
Si tomamos otro ejemplo para el tipo int
const int i[] = {1,2,3};
const int *ii = i // OK
signed const int *si = i; // OK
unsigned const int *usi = i; // Error
Las dos primeras inicializaciones de puntero funcionan como int
sin ningún especificador es equivalente a signed int
(pero esto no es cierto con char
) y, por lo tanto, los tipos son compatibles. La intialización falla en el último caso, ya que const int *
o firm signed const int *
son incompatibles con unsigned const int *
.
"z1y2x3w4"
es const char[9]
y no hay una conversión implícita de const char*
a const signed char*
.
Podrías usar reinterpret_cast
const signed char * AnArrayOfStrings[] = {reinterpret_cast<const signed char *>("z1y2x3w4"),
reinterpret_cast<const signed char *>("Aname")};