Por que são compostos literais em C modificáveis
normalmente associamos 'não modificável' ao termo literal
char* str = "Hello World!";
*str = 'B'; // Bus Error!
No entanto, ao usar literais compostos, descobri rapidamente que eles são completamente modificáveis (e travando no código da máquina gerada, você vê que eles são empurrados na pilha):
char* str = (char[]){"Hello World"};
*str = 'B'; // A-Okay!
estou a compilar com clang-703.0.29
. Esses dois exemplos não deveriam gerar o mesmo código de máquina? Um literal composto é mesmo literal, se é modificável?
editar: um exemplo ainda mais curto iria be:
"Hello World"[0] = 'B'; // Bus Error!
(char[]){"Hello World"}[0] = 'B'; // Okay!
1 answers
Um literal composto é um valor lvalue e os valores dos seus elementos são modificáveis. No caso de
char* str = (char[]){"Hello World"};
*str = 'B'; // A-Okay!
Estás a modificar um literal composto que é legal.
C11-§6.5.2.5/4:
Se o nome do tipo indicar um array de tamanho desconhecido, o tamanho é determinado pela lista de inicialização, conforme especificado em 6.7.9, e o tipo do literal composto é o do tipo de array completo. Caso contrário (quando o nome do tipo especifica um tipo de objecto) , o tipo of the compound literal is that specified by the type name. em ambos os casos, o resultado é um valor lvalue .
Como pode ser visto que o tipo de composto literal é um tipo de array completo e é lvalue, por isso é modificável ao contrário de literais de cadeias de caracteres
A norma também menciona que
§6.5.2.5/7:
Além disso, diz:Literais de texto, e literais compostos com tipos qualificados de const, não necessitam de designar distintos objecto.101
11 exemplo 4 um literal composto apenas para leitura pode ser especificado através de construções como:
(const float []){1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6}
12 exemplo 5 as três expressões seguintes têm significados diferentes:
"/tmp/fileXXXXXX" (char []){"/tmp/fileXXXXXX"} (const char []){"/tmp/fileXXXXXX"}
A primeira sempre tem duração de armazenamento estático e tem array tipo de
char
, mas não precisa ser modificável; as duas últimas têm duração de armazenamento automático quando ocorrem dentro do corpo de uma função, e o primeiro destes dois é modificável .13 exemplo 6 como literais de cordas, literais compostos qualificados de const podem ser colocados em memória apenas de leitura e podem até ser partilhados. Por exemplo,
(const char []){"abc"} == "abc"
Pode produzir 1 Se o armazenamento dos literais for partilhado.