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á usando constexpr
.
constexpr char* str = "some string";
Parece que ele se comportaria de maneira semelhante e const char* str
, portanto, não causaria um aviso, como ocorre antes char*
, mas se comportaria como char* const str
.
Detalhes
Ponteiro constante e ponteiro para uma constante. A diferença entre const char* str
e char* 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 como const char* str
, e não char* 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 de char* str = "some string"
.
- Aviso do compilador para
constexpr char* str = "some string"
:ISO C++11 does not allow conversion from string literal to 'char *const'
- Aviso do compilador para
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 é uma C
única ferramenta e, portanto, não suporta coisas (como constexpr) que são exclusivas C++
.
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.