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.

Foi útil?

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";

O C ++ estados padrão: (secção lex.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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top