O padrão C ++ 11 (ISO / IEC 14882: 2011) diz § C.1.1
:
char* p = "abc"; // valid in C, invalid in C++
Para o C ++, não há problema em apontar para um String Literal, pois qualquer tentativa de modificá-lo leva a uma falha. Mas por que isso é válido em C?
O C ++ 11 diz também:
char* p = (char*)"abc"; // OK: cast added
O que significa que, se um elenco for adicionado à primeira instrução, ele se tornará válido.
Por que o elenco torna a segunda instrução válida em C ++ e como ela é diferente da primeira? Ainda não é prejudicial? Se for o caso, por que o padrão disse que está tudo bem?
char[]
em primeiro lugar. O segundo é umconst_cast
disfarçado.OK
.const
, portanto não eram necessariamenteconst
.Respostas:
Até o C ++ 03, seu primeiro exemplo era válido, mas usava uma conversão implícita obsoleta - uma literal de cadeia de caracteres deve ser tratada como sendo do tipo
char const *
, pois você não pode modificar seu conteúdo (sem causar comportamento indefinido).A partir do C ++ 11, a conversão implícita que havia sido descontinuada foi oficialmente removida; portanto, o código que depende dela (como o seu primeiro exemplo) não deve mais ser compilado.
Você observou uma maneira de permitir que o código seja compilado: embora a conversão implícita tenha sido removida, uma conversão explícita ainda funciona, para que você possa adicionar uma conversão. Eu não entanto, consideraria isso "corrigindo" o código.
Para corrigir o código, é necessário alterar o tipo do ponteiro para o tipo correto:
Por que isso foi permitido em C ++ (e ainda está em C): simplesmente porque há muito código existente que depende dessa conversão implícita, e a quebra desse código (pelo menos sem algum aviso oficial) aparentemente pareceu aos comitês padrão como Uma má ideia.
fonte
char const *p = "abc";
é "válida e segura em ambos C e C ++", e não "válida e segura em qualquer C ou C ++".É válido em C por razões históricas. C tradicionalmente especificava que o tipo de uma string literal era, em
char *
vez deconst char *
, embora a qualificasse dizendo que você não tem permissão para modificá-la.Ao usar uma conversão, você está basicamente dizendo ao compilador que conhece melhor do que as regras de correspondência de tipo padrão e isso torna a atribuição correta.
fonte
char[N]
e foi alterado paraconst char[N]
. Tem informações de tamanho anexadas a ele.char[N]
, mas nãochar*
por exemplo,"abc"
échar[4]
Você também pode usar strdup :
fonte