Tengo una clase con un private char str[256];
y para ello tengo un constructor explícito:
explicit myClass(const char *func)
{
strcpy(str,func);
}
Lo llamo como:
myClass obj("example");
Cuando compilo esto recibo la siguiente advertencia:
conversión obsoleta de constante de cadena a 'char *'
¿Por qué está pasando esto?
c++
string
explicit-constructor
mkamthan
fuente
fuente
strncpy(str, func, 255)
lugar destrcpy(str, func)
una copia más segura. Y luego no olvide agregar el '\ 0' al final de la cadena ya que strncpy no lo agrega.Respuestas:
Este es un mensaje de error que ve cuando tiene una situación como la siguiente:
¿Por qué? Bueno, C y C ++ difieren en el tipo del literal de cadena. En C, el tipo es matriz de caracteres y en C ++ es una matriz constante de caracteres. En cualquier caso, no está permitido cambiar los caracteres del literal de cadena, por lo que la constante en C ++ no es realmente una restricción, sino más bien una cuestión de seguridad de tipo. Una conversión de
const char*
achar*
generalmente no es posible sin un molde explícito por razones de seguridad. Pero para la compatibilidad con versiones anteriores de C, el lenguaje C ++ todavía permite asignar un literal de cadena a aychar*
le da una advertencia acerca de que esta conversión está en desuso.Entonces, en algún lugar te falta uno o más
const
s en tu programa para la corrección constante. Pero el código que nos mostró no es el problema, ya que no hace este tipo de conversión en desuso. La advertencia debe haber venido de otro lugar.fuente
const
delMyClass
constructor ... luego puede solucionarlo agregando la parteconst
posterior.La advertencia:
se da porque estás haciendo algo (no en el código que publicaste) algo como:
El problema es que está intentando convertir un literal de cadena (con tipo
const char[]
) achar*
.Puede convertir un
const char[]
aconst char*
porque la matriz se descompone en el puntero, pero lo que está haciendo es hacer que una mutable sea una constante.Esta conversión probablemente está permitida por compatibilidad con C y solo le da la advertencia mencionada.
fuente
Como respuesta no. 2 por fnieto - Fernando Nieto describe clara y correctamente que esta advertencia se da porque en algún lugar de su código está haciendo (no en el código que publicó) algo como:
Sin embargo, si desea mantener su código sin advertencia también, simplemente realice los cambios respectivos en su código:
Es decir, simplemente emite la
string
constante a(char *)
.fuente
void foo(char* str)
como está? Pensé que no podemos modificarstr
defoo
ninguna manera, incluso el parámetro está escrito como no constante.Hay 3 soluciones:
Solución 1:
Solución 2:
Solución 3:
Las matrices también se pueden usar en lugar de punteros porque una matriz ya es un puntero constante.
fuente
strdup
. A diferencia de su código, asignará espacio para el carácter NUL de terminación y no anulará la asignación.De hecho, un literal de cadena constante no es un const char * ni un char * sino un char []. Es bastante extraño, pero está escrito en las especificaciones de C ++; Si lo modifica, el comportamiento no está definido porque el compilador puede almacenarlo en el segmento de código.
fuente
Quizás puedas probar esto:
Esto funciona para mi
fuente
Resuelvo este problema agregando esta macro al comienzo del código, en algún lugar. O
<iostream>
agrégalo, jeje.fuente
C_TEXT
está bien para una llamada a función (foo(C_TEXT("foo"));
), pero está pidiendo un comportamiento indefinido si el valor se almacena en una variable comochar *x = C_TEXT("foo");
: cualquier uso dex
(aparte de la asignación) es un comportamiento indefinido porque la memoria a la que apunta se ha liberado.Una razón para este problema (que es aún más difícil de detectar que el problema con el
char* str = "some string"
que otros han explicado) es cuando está usandoconstexpr
.Parece que se comportaría de manera similar y
const char* str
, por lo tanto, no causaría una advertencia, como ocurre anteschar*
, sino que se comporta comochar* const str
.Detalles
Puntero constante y puntero a una constante. La diferencia entre
const char* str
, ychar* const str
se puede explicar de la siguiente manera.const char* str
: Declara que str es un puntero a un const char. Esto significa que los datos a los que apunta este puntero son constantes. El puntero se puede modificar, pero cualquier intento de modificar los datos arrojaría un error de compilación.str++ ;
: VÁLIDO . Estamos modificando el puntero, y no los datos apuntados.*str = 'a';
: NO VÁLIDO . Estamos tratando de modificar los datos que se apuntan.char* const str
: Declara que str es un puntero constante para char. Esto significa que el punto ahora es constante, pero los datos que se apuntan también no lo son. El puntero no se puede modificar, pero podemos modificar los datos utilizando el puntero.str++ ;
: NO VÁLIDO . Estamos tratando de modificar la variable del puntero, que es una constante.*str = 'a';
: VÁLIDO . Estamos tratando de modificar los datos que se apuntan. En nuestro caso, esto no causará un error de compilación, pero sí un error de tiempo de ejecución , ya que la cadena probablemente irá a una sección de solo lectura del binario compilado. Esta afirmación tendría sentido si hubiéramos asignado dinámicamente memoria, por ejemplo.char* const str = new char[5];
.const char* const str
: Declara que str es un puntero constante para un char constante. En este caso, no podemos modificar el puntero ni los datos a los que se apunta.str++ ;
: NO VÁLIDO . Estamos tratando de modificar la variable del puntero, que es una constante.*str = 'a';
: NO VÁLIDO . Estamos tratando de modificar los datos apuntados por este puntero, que también es constante.En mi caso, el problema era que esperaba
constexpr char* str
comportarme comoconst char* str
y nochar* const str
, ya que visualmente parece más cercano al anterior.Además, la advertencia generada para
constexpr char* str = "some string"
es ligeramente diferente dechar* str = "some string"
.constexpr char* str = "some string"
:ISO C++11 does not allow conversion from string literal to 'char *const'
char* str = "some string"
:ISO C++11 does not allow conversion from string literal to 'char *'
.Propina
Puede usar el convertidor de inglés C gibberish to para convertir
C
declaraciones en declaraciones en inglés fácilmente comprensibles, y viceversa. Esta es unaC
herramienta única y, por lo tanto, no admitirá cosas (como constexpr) que son exclusivas deC++
.fuente
También tengo el mismo problema. Y lo que hice simplemente fue agregar const char * en lugar de char *. Y el problema resuelto. Como otros han mencionado anteriormente, es un error compatible. C trata las cadenas como matrices de caracteres mientras que C ++ las trata como matrices de caracteres constantes.
fuente
Para lo que vale, creo que esta clase de contenedor simple es útil para convertir cadenas de C ++ a
char *
:fuente
A continuación se ilustra la solución: asigne su cadena a un puntero variable a una matriz constante de caracteres (una cadena es un puntero constante a una matriz constante de caracteres más información de longitud):
fuente