Eu tenho uma aula com um private char str[256];
e por isso eu tenho um construtor explícito:
explicit myClass(const char *func)
{
strcpy(str,func);
}
Eu chamo como:
myClass obj("example");
Ao compilar isso, recebo o seguinte aviso:
conversão descontinuada da constante de cadeia para 'char *'
Por que isso está acontecendo?
c++
string
explicit-constructor
mkamthan
fonte
fonte
strncpy(str, func, 255)
vez destrcpy(str, func)
obter uma cópia mais segura. E não esqueça de adicionar o '\ 0' no final da string, pois o strncpy não o adiciona.Respostas:
Esta é uma mensagem de erro que você vê sempre que tem uma situação como a seguinte:
Por quê? Bem, C e C ++ diferem no tipo da string literal. Em C, o tipo é array de caracteres e, em C ++, é um array constante de caracteres. De qualquer forma, você não tem permissão para alterar os caracteres da string literal, portanto a const no C ++ não é realmente uma restrição, mas mais uma coisa de segurança de tipo. Uma conversão de
const char*
parachar*
geralmente não é possível sem uma conversão explícita por motivos de segurança. Mas, para compatibilidade com versões anteriores com C, a linguagem C ++ ainda permite atribuir uma string literal achar*
e fornece um aviso sobre a descontinuação dessa conversão.Então, em algum lugar em que você está perdendo um ou mais
const
s no seu programa para correção de const. Mas o código que você nos mostrou não é o problema, pois não faz esse tipo de conversão preterida. O aviso deve ter vindo de outro lugar.fonte
const
doMyClass
construtor ... e corrigi-lo adicionando aconst
parte de trás.O aviso:
é dado porque você está fazendo em algum lugar (não no código que você postou) algo como:
O problema é que você está tentando converter uma string literal (com o tipo
const char[]
) emchar*
.Você pode converter um
const char[]
paraconst char*
porque a matriz decai para o ponteiro, mas o que você está fazendo é tornar uma mutável uma constante.Essa conversão provavelmente é permitida para compatibilidade com C e fornece apenas o aviso mencionado.
fonte
Como resposta não. 2 por fnieto - Fernando Nieto descreve clara e corretamente que esse aviso é dado porque em algum lugar do seu código você está fazendo (não no código que você postou) algo como:
No entanto, se você deseja manter seu código livre de aviso, faça as alterações correspondentes no seu código:
Ou seja, basta lançar a
string
constante para(char *)
.fonte
void foo(char* str)
como está? Eu pensei que não podemos modificarstr
defoo
qualquer maneira, mesmo o parâmetro é escrito como não-const.Existem 3 soluções:
Solução 1:
Solução 2:
Solução 3:
Matrizes também podem ser usadas em vez de ponteiros, porque uma matriz já é um ponteiro constante.
fonte
strdup
. Diferentemente do seu código, ele alocará espaço para o caractere NUL final e não excederá a alocação.De fato, uma constante de string literal não é um const char * nem um char *, mas um char []. É bastante estranho, mas escrito nas especificações c ++; Se você modificá-lo, o comportamento é indefinido porque o compilador pode armazená-lo no segmento de código.
fonte
Talvez você possa tentar o seguinte:
Funciona para mim
fonte
Eu resolvo esse problema adicionando essa macro no início do código, em algum lugar. Ou adicione
<iostream>
, hehe.fonte
C_TEXT
é bom para uma chamada de função (foo(C_TEXT("foo"));
), mas clama por comportamento indefinido se o valor for armazenado em uma variável comochar *x = C_TEXT("foo");
- qualquer uso dex
(além da atribuição) é um comportamento indefinido porque a memória para a qual está apontando foi liberada.Uma razão para esse problema (que é ainda mais difícil de detectar do que o problema
char* str = "some string"
- que outros explicaram) é quando você está usandoconstexpr
.Parece que ele se comportaria de maneira semelhante e
const char* str
, portanto, não causaria um aviso, como ocorre anteschar*
, mas se comportaria comochar* const str
.Detalhes
Ponteiro constante e ponteiro para uma constante. A diferença entre
const char* str
echar* const str
pode ser explicada da seguinte forma.const char* str
: Declare str como um ponteiro para um const char. Isso significa que os dados para os quais esse ponteiro está apontando para ele são constantes. O ponteiro pode ser modificado, mas qualquer tentativa de modificar os dados geraria um erro de compilação.str++ ;
: VÁLIDO . Estamos modificando o ponteiro, e não os dados que estão sendo apontados.*str = 'a';
: INVÁLIDO . Estamos tentando modificar os dados que estão sendo apontados.char* const str
: Declare str como um ponteiro const para char. Isso significa que agora o ponto é constante, mas os dados também estão sendo apontados. O ponteiro não pode ser modificado, mas podemos modificar os dados usando o ponteiro.str++ ;
: INVÁLIDO . Estamos tentando modificar a variável ponteiro, que é uma constante.*str = 'a';
: VÁLIDO . Estamos tentando modificar os dados que estão sendo apontados. No nosso caso, isso não causará um erro de compilação, mas causará um erro de tempo de execução , pois a string provavelmente entrará em uma seção somente leitura do binário compilado. Essa afirmação faria sentido se alocássemos memória dinamicamente, por exemplo.char* const str = new char[5];
.const char* const str
: Declare str como um ponteiro const para um const char. Nesse caso, não podemos modificar o ponteiro, nem os dados que estão sendo apontados.str++ ;
: INVÁLIDO . Estamos tentando modificar a variável ponteiro, que é uma constante.*str = 'a';
: INVÁLIDO . Estamos tentando modificar os dados apontados por esse ponteiro, que também é constante.No meu caso, a questão era que eu esperava
constexpr char* str
me comportar comoconst char* str
, e nãochar* const str
, já que visualmente parece mais próximo do primeiro.Além disso, o aviso gerado para
constexpr char* str = "some string"
é um pouco 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 *'
.Dica
Você pode usar o conversor C gibberish ↔ English para converter
C
declarações em instruções inglesas facilmente compreensíveis e vice-versa. Esta é umaC
única ferramenta e, portanto, não suporta coisas (como constexpr) que são exclusivasC++
.fonte
Eu também tenho o mesmo problema. E o que eu fiz foi apenas adicionar const char * em vez de char *. E o problema resolvido. Como outros já mencionaram acima, é um erro compatível. C trata as strings como matrizes de caracteres, enquanto o C ++ as trata como matrizes const char.
fonte
Quanto vale a pena, acho que essa classe simples de wrapper é útil para converter cadeias de caracteres C ++ em
char *
:fonte
A seguir, ilustra a solução, atribua sua string a um ponteiro variável a uma matriz constante de char (uma string é um ponteiro constante a uma matriz constante de char - além de informações de comprimento):
fonte