Pergunta

A codificação apresentação estilo que eu assisti recentemente no escritório defendeu que as variáveis ??não deve ser atribuído (para um valor padrão), quando eles são definidos. Em vez disso, eles devem ser atribuído um valor padrão pouco antes de seu uso. Então, algo como

int a = 0;

deve ser desaprovada.

Obviamente, um exemplo de 'int' é simplista, mas o mesmo segue para outros tipos também como ponteiros etc.

Além disso, foi também mencionou que os compiladores compatíveis C99 agora lançar um aviso no acima mencionado caso.

A abordagem acima parece útil para mim apenas para estruturas ou seja, você Memset-los apenas antes do uso. Isso seria eficiente se a estrutura é usada (ou cheio) apenas em uma perna erro.

Para todos os outros casos, acho definir e atribuir a um valor padrão de um exercício prudente como eu encontrei um monte de erros por causa de ponteiros inicializado-un tanto ao escrever e manter o código. Além disso, acredito C ++ via construtores também defende a mesma abordagem ou seja, definir e atribuir.

Eu estou querendo saber por que (se) padrão C99 não como definir e atribuir. É a sua algum mérito considerável em fazer o que a apresentação estilo de codificação defendido?

Foi útil?

Solução

Normalmente eu recomendo inicializar variáveis ??quando elas são definidas se o valor que eles devem ter é conhecido, e variáveis ??de licença uninitialised se o valor não é. De qualquer forma, colocá-los tão perto de seu uso como escopo regras permitem.

Em vez disso, eles devem ser atribuído um valor padrão apenas antes da sua utilização.

Normalmente, você não deve usar um valor padrão em tudo. Em C99 você pode misturar código e declarações, então não há nenhum ponto que define a variável antes de atribuir um valor a ela. Se você sabe o valor que deveria tomar, então não há nenhum ponto em ter um valor padrão.

Além disso, foi também mencionou que os compiladores compatíveis C99 agora lançar um aviso no acima mencionado caso.

Não para o caso de você mostrar - você não receber um aviso por ter int x = 0;. Eu suspeito fortemente que alguém tem isso mista. Compiladores avisar se você usar uma variável sem atribuir um valor a ela, e se você tem:

... some code ...

int x;

if ( a )
    x = 1;
else if ( b )
    x = 2;
// oops, forgot the last case else x = 3;

return x * y;

, em seguida, você receberá um aviso de que x pode ser usado sem ser inicializado, pelo menos com gcc.

Você não receberá um aviso se você atribuir um valor a x antes do if, mas é irrelevante se a atribuição é feita como um initialiser ou como uma declaração separada.

A menos que você tenha uma razão específica para atribuir o valor duas vezes para dois dos ramos, não há nenhum ponto de atribuir o valor padrão de x em primeiro lugar, como ele pára o compilador avisando que você cobriu todos os ramos.

Outras dicas

não tal exigência (ou mesmo orientação que eu saiba) em C99, nem o compilador avisá-lo sobre isso. É simplesmente uma questão de estilo.

Quanto estilo de codificação está em causa, eu acho que você levou as coisas muito literalmente. Por exemplo, a sua declaração é certo no caso a seguir ...

int i = 0;

for (; i < n; i++)
        do_something(i);

... ou mesmo em ...

int i = 1;

[some code follows here]

while (i < a)
        do_something(i);

... mas há outros casos que, na minha opinião, são melhor tratadas com um "declarar e atribuir" mais cedo. Considere estruturas construídas na pilha ou vários OOP construções, como em:

struct foo {
        int bar;

        void *private;
};

int my_callback(struct foo *foo)
{
        struct my_struct *my_struct = foo->private;

        [do something with my_struct]

        return 0;
}

Ou como em (C99 struct initializers):

void do_something(int a, int b, int c)
{
        struct foo foo = {
                .a        = a,
                .b        = b + 1,
                .c        = c / 2,
        };

        write_foo(&foo);
}

Eu meio que coincide com o conselho, embora eu não estou completamente certo o padrão diz nada sobre isso, e eu duvido muito o pouco sobre os avisos do compilador é verdade.

A coisa é, compiladores modernos podem fazer e detectar o uso de variáveis ??uninitialised. Se você definir suas variáveis ??para os valores padrão na inicialização, você perde que a detecção. E valores padrão pode causar erros também; certamente, no caso do seu exemplo, int a = 0;. Quem diz 0 é um valor apropriado para a?

Na década de 1990, o conselho teria sido errado. Hoje em dia, é correto.

Acho que é muito útil para pré-atribuir alguns dados padrão para variáveis ??de modo que eu não tenho que fazer (como muitos) verificações nulos no código.

Eu vi tantos erros devido a ponteiros não inicializados que eu sempre defendeu a declarar cada variável com NULL_PTR e cada primitivewith algum valor / padrão inválido.

Desde que eu trabalho em RTOS e alto desempenho, mas os sistemas de recursos baixos, é possível que os compiladores que usamos não pegar uso não-inicializado. Embora eu duvide compiladores modernos também pode ser invocado 100%.

Em grandes projetos onde de macro são usados ??extensivamente, tenho visto cenários raros em que, mesmo Kloclwork / Purify não conseguiram encontrar o uso não-inicializado.

Então eu digo ficar com ela enquanto você estiver usando o bom e velho C / C ++.

línguas modernas como .Net pode garantir para inicializar varaibles, ou dar um erro do compilador para o uso variável não inicializada. Após ligação faz uma análise de desempenho e valida que há um acerto de desempenho de 10-20% para .NET. A análise está em muito detalhe e é explicado bem.

http://www.codeproject.com/KB/dotnet/DontInitializeVariables.aspx

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