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")};