Âmbito de (string) literais
Pergunta
Eu sempre tentar evitar a retornar strings literais, porque temo que eles não estão definidas fora da função. Mas eu não tenho certeza se este é o caso. Vamos tomar, por exemplo, esta função:
const char *
return_a_string(void)
{
return "blah";
}
É este código correto? Ele faz o trabalho para mim, mas talvez ele só funciona para meu compilador (gcc). Então a questão é, se (string) literais têm um escopo ou são presentes / definiu o tempo todo.
Solução
Este código é muito bem em todas as plataformas. A string é compilado no binário como um literal cadeia de caracteres estática. Se você estiver no Windows, por exemplo, você pode até mesmo abrir o seu .exe com bloco de notas e procurar a própria corda.
Uma vez que é um escopo literal corda estática não importa.
Cordas pooling:
Uma coisa a olhar para fora é que, em alguns casos, strings literais idênticas podem ser "agrupados" para economizar espaço no arquivo executável. Neste caso, cada string literal que era o mesmo poderia ter o mesmo endereço de memória. Você nunca deve assumir que ele irá ou não ser o caso, porém.
Na maioria dos compiladores você pode escolher se quer ou não usar pooling corda estática para stirng literais.
Tamanho máximo de strings literais:
Vários compiladores têm um tamanho máximo para o literal string. Por exemplo, com VC ++ este é aproximadamente 2.048 bytes.
Modificar um literal de cadeia dá um comportamento indefinido:
Modificando um literal de cadeia nunca deve ser feito. Ele tem um comportamento indefinido.
char * sz = "this is a test";
sz[0] = 'T'; //<--- undefined results
Ampla cordas literais:
Todos os itens acima se aplica igualmente a strings literais de largura.
Exemplo: L "esta é uma grande literal string";
1 Um literal string é uma sequência de caracteres (tal como definidos em lex.ccon ) entre aspas duplas, opcionalmente, começando com o letra L, como em "..." ou L "...". Um literal de cadeia que não começa com L é um literal de cadeia ordinária, também referida como uma estreita literal string. Um literal de cadeia comum tem tipo "matriz de n const char" e armazenagem estática duração ( basic.stc ), onde n é o Tamanho da cadeia, tal como definido abaixo, e é inicializada com o dado personagens. Um literal de cadeia que começa com L, tais como L "asdf", é uma ampla literal string. Uma grande literal string tem tipo "leque de n wchar_t const" e tem a duração de armazenamento estático, onde n é o tamanho do da cadeia, tal como definido abaixo, e é inicializada com o carac- dado ters.
2 Se todas as strings literais são distintas (isto é, são armazenados em nonoverlapping objectos) é definido pela implementação. O efeito do tentar modificar um literal de cadeia é indefinido.
Outras dicas
Eu dar-lhe um exemplo para que sua confusão se torna um pouco clara
char *f()
{
char a[]="SUMIT";
return a;
}
este trabalho não vai.
e
char *f()
{
char *a="SUMIT";
return a;
}
isso funciona.
Motivo: "SUMIT" é um literal que tem um alcance global. enquanto a matriz, que é apenas uma sequência de caracteres { 'S', 'L', 'M', 'I', "T '' \ 0' } tem um alcance limitado e desaparece assim que o programa é retornado.
Espero que isso ajude
Este é válida em C (ou C ++), como já foi explicado.
A única coisa que posso pensar que atente para é que se você estiver usando dlls, em seguida, o ponteiro não permanecerá válida se a DLL que contém este código é descarregado.
A C (ou C ++) padrão não entender ou ter em conta a carga e código de descarga em tempo de execução, então qualquer coisa que faz que as conseqüências definido pela implementação rosto vai: neste caso, a consequência é que o literal string, que é suposto ter duração de armazenamento estático, aparece a partir do POV do código de chamada não persistir durante toda a duração do programa.
Sim, isso é bom. Eles vivem em uma tabela de cadeia global.
Não, strings literais não tem alcance, para que o seu código é garantido que funcione em todas as plataformas e compiladores. Eles são armazenados em imagem binária do seu programa, assim você sempre pode acessá-los. No entanto, tentando escrever para eles (por jogar fora o const
) vai levar a um comportamento indefinido.
Você realmente retornar um ponteiro para a string terminada em zero armazenado na seção de dados do executável, uma área carregada quando você carregar o programa. Basta evitar para tentar mudar os personagens, pode dar resultados imprevisíveis ...
É muito importante fazer nota dos resultados indefinidos que Brian mencionados. Desde que você tenha declarado a função como retornando um char const * Tipo, você deve estar bem, mas em muitas plataformas strings literais são colocados em um segmento só de leitura no executável (normalmente o segmento de texto) e modificá-los fará com que uma violação de acesso na maioria das plataformas.