web-dev-qa-db-fra.com

C - Vérifier si Integer est assigné

Comment déterminer si un entier est non attribué?

int i; /* no assignment */

if (/* conditional statement here to check if int i is unassigned or not */) {
   printf("Integer is unassigned!\n");
} else {
   printf("Integer is assigned!\n");
}
27
Timothy

Tu ne peux pas. Il contiendra un contenu "non défini", ce qui signifie qu'il contiendra ce qui se trouve dans cet emplacement de mémoire à ce moment-là.

. . . à moins que i ne soit déclaré à la portée globale, il sera initialisé à zéro.

22
Binary Worrier

C ne prend pas intrinsèquement en charge cela - tout comme il ne supporte pas intrinsèquement la vérification des limites sur les tableaux. C'est un compromis entre vitesse/efficacité et sécurité.

En général ... initialisez vos variables.

8
Amber

C'est très simple. Vous savez qu'il n'est pas affecté car vous ne l'avez pas initialisé.

6
anon

Si i est global ou statique, sa valeur sera 0; sinon, sa valeur peut être quelconque et il est impossible de savoir s'il s'agit ou non de garbage.

4
qrdl

Vous pourrez peut-être demander des avertissements au compilateur si vous utilisez des valeurs non initialisées. Cependant, ils ne sont pas totalement fiables - vous obtenez parfois des faux positifs lorsque le DFA n'est pas aussi intelligent que vous le souhaiteriez, et peut-être des faux négatifs occasionnels (j'espère que non, mais je ne promets rien).

Pour GCC:

-Wuninitialized -O1

Si vous voulez écrire du code conditionnel:

int a = 3;
int b;
int *p = (Rand() > Rand_MAX/2) ? &a : &b;
if (is_uninitialized(*p)) // blah

alors vous n'avez pas de chance. Contrairement à certains langages dynamiques, C n'a pas de concept de "valeur indéfinie". Si une variable n'est pas initialisée, aucune valeur spéciale ne peut être testée pour plus tard. Aucune valeur ne lui est attribuée. Par conséquent, ce qui se produit lorsque vous utilisez la variable n'est pas défini.

4
Steve Jessop

Comme d'autres l'ont noté, vous ne pouvez pas écrire un programme C qui détecte si l'une de ses propres variables n'est pas initialisée et vous devez vous assurer que les variables sont toujours initialisées.

  • Si votre objectif est de vous assurer que toutes les variables sont initialisées, un outil tel que valgrind peut détecter les utilisations de variables non initialisées dynamiquement , grâce à une analyse d’exécution coûteuse.

  • Si votre objectif est de vous assurer que les données privées sont initialisées exactement une fois, la méthode habituelle consiste à les protéger avec

    int i;
    static bool initialized = 0;
    
    ... 
    if (!initialized) {
      initialized = 1;
      i = ... i's initial value ...;
    }
    
4
Norman Ramsey

Généralement, les variables sont définies sur 0 par la bibliothèque C, mais pas nécessairement. 

Mais fondamentalement, vous ne pouvez pas. Attribuez-leur une valeur par défaut dans la définition, par exemple:

int i = 0; /* Or what ever value you know won't be used elsewhere */

Ensuite, si vous exécutez du code et souhaitez vérifier si la valeur a été définie ici, vous pouvez comparer votre valeur initiale.

1
Makis

Comme pour toutes les réponses précédentes, il n’existe aucun moyen de le détecter au moment de l’exécution. Cependant, presque tout outil d’analyse de code statique avec vous avertit des variables non affectées.

1
KIV

L'utilisation d'une variable avant l'initialisation (ou l'affectation) est une cause grave d'erreurs. Vous ne pouvez pas le vérifier de manière fiable au moment de l'exécution, mais vous pouvez le détecter pendant ou avant la compilation.

Je suggère pas de le vérifier dans le code. Parce que cela est susceptible de provoquer des avertissements pour le compilateur (la variable 'i' est utilisée avant qu'une valeur lui ait été affectée), introduisez de nouvelles erreurs et avez très peu de chance de réussir dans les programmes de moyenne à grande taille. 

La meilleure méthode consiste à utiliser des outils d'analyse de code statique (tels que QA/C ou PCLint). Utiliser un compilateur avec un niveau de sensibilité d'alerte élevé est une option gratuite, avec beaucoup moins de couverture que les outils spécialisés.

Si vous effectuez des révisions de code, vous pouvez également inclure une vérification des variables non initialisées dans la liste de vérification. Ce n'est pas une garantie, mais cela déclenchera des vérifications manuelles des réviseurs.

Si vous souhaitez vérifier l'exécution, vous pouvez commencer par initialiser les variables à une valeur hors limites. Par exemple, -1 pour une valeur par ailleurs positive. Ensuite, vous pouvez vérifier 

#define UNASSIGNED_VALUE -1
    static int number_of_apples = UNASSIGNED_VALUE;
    if (UNASSIGNED_VALUE == number_of_apples)
    {
       // error handling
    }

il ne s'agit pas d'une véritable variable "non centralisée", mais vous pouvez au moins détecter si des affectations d'exécution dans la plage légale ont été effectuées.

1
Adriaan

En C, un entier prend une valeur indéfinie lors de sa création. Cela signifie que si votre première utilisation de cet entier provient d'un registre/emplacement de mémoire/périphérique contenant 5893872, c'est la valeur de cet entier. (Le kilométrage varie pour la compilation de débogage/publication.)

La méthode habituelle consiste à utiliser un défaut absurde:

int number_of_widgets = -1;

... ou un drapeau pour indiquer son état:

int number_of_widgets;
int number_of_widgets_assigned = 0;

if (number_of_widgets_assigned)
  do something
else
  do something else
number_of_widgets_assigned = 1;

Il n'y a pas d'autre moyen de détecter si quelque chose a été assigné - à moins que vous ne vouliez entrer dans les fonctionnalités de débogage de votre matériel et je suppose que ce n'est pas le propos de cette conversation.

0
Sniggerfardimungus

En C #, j'utiliserais:

Nullable<int> i = null; /* null assignment */

if (i == null) {
   printf("Integer is unassigned!\n");
} else {
   printf("Integer is assigned!\n");
}

Je ne sais pas si cela se traduirait par C, cependant.

0
Akaoni

Vérifier si une variable que vous utilisez est ou non initialisée (assignée) à l'exécution est notoirement difficile pour C. Elle n'est pas prise en charge par la langue, et les informations disponibles à l'exécution sont tout simplement insuffisantes pour une détection parfaite des valeurs non initialisées. Les outils d’analyse dynamique, tels que Valgrind/Memcheck, nécessitent beaucoup de travail (garder la trace de chaque octet de mémoire dans l’espace adresse de votre processus, puis examiner chaque magasin pour marquer un octet comme étant intiialisé) afin de déterminer si la valeur utilisée est ou non initialisée. sont toujours susceptibles de faux positifs.

Si vous essayez simplement de minimiser de telles erreurs dans vos programmes, les outils d'analyse statique tels que lint peuvent vous informer de manière utile si vous utilisez ou non des variables non initialisées. En fait, je pense que la plupart des compilateurs feront de leur mieux pour vous le dire quand vous le ferez (bien qu'ils ne soient certainement pas parfaits).

0
Falaina