Question

Une présentation de style de codage que j'ai assisté dernièrement dans le bureau a préconisé que les variables ne doivent PAS être affectées (à une valeur par défaut) quand ils sont définis. Ils devraient plutôt se voir attribuer une valeur par défaut juste avant leur utilisation. Donc, quelque chose comme

int a = 0;

doit être désapprouvé.

De toute évidence, un exemple de « int » est simpliste, mais le même suit pour d'autres types aussi comme pointeurs etc.

En outre, il a également été mentionné que les compilateurs compatibles C99 jettent maintenant dans le cas ci-dessus mentionné un avertissement.

L'approche ci-dessus semble utile pour moi que pour les structures à savoir que vous les Memset seulement avant utilisation. Cela serait efficace si la structure est utilisée (ou rempli) que dans une jambe d'erreur.

Pour tous les autres cas, je trouve la définition et l'affectation à une valeur par défaut d'un exercice prudent comme je l'ai rencontré beaucoup de bugs en raison de pointeurs non initialisé à la fois lors de l'écriture et la maintenance du code. De plus, je crois que C ++ par les constructeurs préconise également la même approche à savoir définir et attribuer.

Je me demande pourquoi (si) la norme C99 n'aime pas la définition et l'attribution. Leur aucun mérite considérable à faire ce que la présentation de style de codage préconisé?

Était-ce utile?

La solution

En général, je recommande des variables initialisant quand ils sont définis si la valeur qu'ils devraient avoir est connu, et laisse les variables non initialisées si la valeur est différente. De toute façon, les mettre au plus près de leur utilisation comme règles de cadrage permettent.

  

Au lieu de cela, ils devraient se voir attribuer une valeur par défaut juste avant leur utilisation.

En général, vous ne devriez pas utiliser une valeur par défaut du tout. En C99, vous pouvez mélanger le code et déclarations, donc il n'y a pas de point définissant la variable avant d'attribuer une valeur. Si vous connaissez la valeur, il est censé prendre, alors il n'y a pas de point d'avoir une valeur par défaut.

  

En outre, il a également été mentionné que les compilateurs compatibles C99 jettent maintenant dans le cas ci-dessus mentionné un avertissement.

Ne pas le cas, vous montrer - vous ne recevez pas un avertissement pour avoir int x = 0;. Je soupçonne fortement que quelqu'un a ce mêlé. Compilateurs avertissent si vous utilisez une variable sans attribuer une valeur à elle, et si vous avez:

... some code ...

int x;

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

return x * y;

alors vous obtiendrez un avertissement que x peut être utilisé sans être initialisées, au moins avec gcc.

Vous ne recevez un avertissement si vous attribuez une valeur à x avant la if, mais il est indifférent de savoir si la cession est faite comme un ou une initialiseur déclaration distincte.

Sauf si vous avez une raison particulière d'attribuer deux fois la valeur deux des branches, il n'y a pas de point attribuer la valeur par défaut à x d'abord, car il arrête le compilateur vous avertit que vous avez couvert toutes les branches.

Autres conseils

Il y a pas cette exigence (ou même ligne directrice que je suis au courant) en C99, ni le compilateur vous préviens à ce sujet. Il est tout simplement une question de style.

En ce qui concerne le style de codage concerne, je pense que vous avez pris les choses trop à la lettre. Par exemple, votre déclaration est juste dans le cas suivant ...

int i = 0;

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

... ou même dans ...

int i = 1;

[some code follows here]

while (i < a)
        do_something(i);

... mais il y a d'autres cas qui, dans mon esprit, sont mieux avec un début manipulé « déclarer et attribuer ». Considérons les structures construites sur la pile ou différentes constructions POO, comme dans:

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 comme dans (initializers struct C99):

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

        write_foo(&foo);
}

Je sorte d'accord avec l'avis, même si je ne suis pas tout à fait sûr que la norme ne dit rien à ce sujet, et je doute fort peu sur le avertissements du compilateur est vrai.

La chose est, les compilateurs modernes peuvent et détecter l'utilisation de variables non initialisées. Si vous définissez vos variables aux valeurs par défaut à l'initialisation, vous perdez cette détection. Et les valeurs par défaut peuvent causer des bugs trop; certainement dans le cas de votre exemple, int a = 0;. Qui a dit que 0 est une valeur appropriée pour a?

Dans les années 1990, les conseils aurait eu tort. De nos jours, il est correct.

Je trouve très utile d'effectuer une pré-assigner des données par défaut aux variables afin que je ne dois pas le faire (comme beaucoup) contrôles nuls dans le code.

Je l'ai vu tant de bogues en raison de pointeurs non initialisées que j'ai toujours plaidé en faveur de déclarer chaque variable avec NULL_PTR et chaque primitivewith certains invalides / valeur par défaut.

Depuis que je travaille sur RTOS et hautes performances, mais les systèmes à faible ressources, il est possible que les compilateurs que nous utilisons ne prennent pas l'utilisation non-initialisé. Bien que je doute des compilateurs modernes peuvent aussi se fier à 100%.

Dans les grands projets où de macro sont largement utilisés, j'ai vu des scénarios rares où même Kloclwork / Purifier ont échoué à trouver une utilisation non initialisé.

Je dis donc rester avec elle aussi longtemps que vous utilisez le bon vieux C / C ++.

langues modernes comme .Net peuvent garantir pour initialiser varaibles, ou donner une erreur de compilateur pour un usage variable non initialisée. Lien suivant fait une analyse de la performance et valide qu'il ya une performance de 10-20% atteint pour .NET. L'analyse est en détail tout à fait et est bien expliqué.

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top