2015-11-29 2 views
-4

Je sais qu'il y a un avertissement non initialisé dans gcc qui peut vous indiquer si une variable n'est pas initialisée. C'est clair pour moi. Mais je veux savoir ce qui est "Peut-Initialisé" avertissement?qu'est-ce que l'avertissement Wmaybe-unitialized de gcc

GCC ne sait pas s'il est initialisé ou non. Ou considérez ceci, le code est initialisé correctement et GCC pense "peut-être" qu'il n'est pas initialisé. Si le compilateur ne sait pas pourquoi je devrais avoir cet avertissement?

Maintenant, je peux désactiver l'avertissement avec -Wno-peut-être-non initialisé ou faire une correction dans le code. Mais ma question est: qu'est-ce que cela veut dire? Pourquoi gcc pense qu'il est peut-être non initialisé. GCC est sûr que la variable est initialisée car je ne reçois pas -Wininitialized.

J'utilise GCC 4.8 Fedora 21 x86_64

J'apprécierions également si quelqu'un pourrait montrer comment cet avertissement se déclenche.

+0

Attention, vous pouvez initialiser votre variable à une valeur par défaut telle que 0. Il vaut probablement mieux utiliser la mauvaise valeur de 0 par accident qu'une valeur non initialisée qui provoque un comportement indéfini. Le moindre de deux maux. –

+0

convenu. Mais cela ne devrait pas être un avertissement Wunitialized? – rkm

+0

Comme expliqué dans la réponse, gcc ne peut pas être sûr si l'utilisation non initialisée se produit ou non. –

Répondre

3

Vous devriez vraiment regarder dans le manuel de GCC avant de poser de telles questions.

Pour une variable automatique, s'il existe un chemin de l'entrée fonction à une utilisation de la variable qui est initialisé, mais il existe d'autres chemins pour lesquels la variable n'est pas initialisé, les émet des compilateur un avertissement s'il ne peut pas prouver que les chemins non initialisés ne sont pas exécutés lors de l'exécution. Ces avertissements sont rendus facultatifs car GCC n'est pas assez intelligent pour voir toutes les raisons pour lesquelles le code peut être correct malgré l'apparition d'une erreur.

Cet avertissement est généré lorsque GCC ne sait pas si une variable est initialisée ou non. Il est émis lorsqu'une variable n'est pas toujours initialisée.

Voici par exemple légèrement modifié du manuel:

void foo(int y) 
{ 
    int x; 
    switch (y) 
    { 
     case 1: x = 1; 
     break; 
     case 2: x = 4; 
     break; 
     case 3: x = 5; 
    } 
    bar(x); 
} 
+0

il s'agit d'un avertissement non initialisé. ma question est peut-être-non initialisée – rkm

+0

http://stackoverflow.com/questions/14132898/gcc-wuninitialized-wmaybe-uninitialized-issues – rkm

+0

@rashad Meh. Je ne comprends pas de quoi tu parles. J'ai cité le manuel de GCC pour '-Wmaybe-uninitialized' (https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html) et vous dites' c'est un avertissement non initialisé. Ma question concerne peut-être uninitialized'. – HolyBlackCat

1

Il y a des cas où le compilateur peut détecter clairement que quelque chose n'est pas initialisé:

void func1(int x); 

void func() 
{ 
    int x; 
    func1(x); // x is definitely not initialized when calling func1; 
} 

Mais dans certains cas, la variable CAN a été initialisé:

void func(int y) 
{ 
    int x; 
    if (y == 1) 
     x = 7; 
    else if (y == 2) 
     x = 14; 
    // If we get here, is x initialized or not? 
    func1(x); 
} 

Maintenant, si vous et moi savons que à y est TOUJOURS onw ou deux, alors le code ci-dessus n'a pas de problème. Toutefois, si nous l'appelons y comme trois, x n'a pas été initialisé et func1 fonctionnera sur une valeur non spécifiée. Si vous activez -Wmaybe-uninitialized, le compilateur avertira dans ce cas.

La solution est de dire au compilateur de ne pas attendre une autre valeur, par exemple en utilisant un assert:

void func(int y) 
{ 
    int x; 
    assert(y == 1 || y == 2 && "Can't deal with y not in { 1, 2 } "); 
    if (y == 1) 
     x = 7; 
    else if (y == 2) 
     x = 14; 
    // If we get here, is x initialized or not? 
    func1(x); 
} 

Maintenant, le compilateur savoir que le résultat de la assert ne permet pas d'être y autre chose que 1 ou 2, et donc toutes les valeurs valides sont couvertes. Les valeurs non valides sont interceptées par le assert qui ne retourne pas.

[Bien entendu, la norme ne stipule pas que le assert a cet effet. C'est un effet de l'analyse des flux d'appels en conjonction avec l'analyse des flux de données et la compréhension de ce que fait assert - Je sais que gcc et clang comprennent tous deux ce type de construction et vont heureusement accepter le code ci-dessus sans avertissement]