Erreurs, bugs, questions - page 2889

 
Roman:

Je pensais que cette MQ avait été supprimée.

Les variables globales semblent être initialisées à zéro, mais j'ai vu des initialisations différentes dans le corps des fonctions lors du premier passage. J'essaie de toujours initialiser avant l'utilisation. Bien que je sois d'accord, le comportement doit être sans ambiguïté.

Et une autre déclaration dans le corps de la boucle, entre parenthèses, rend la variable locale à la boucle. Ce n'est pas dans la documentation.

 
Roman:

De plus, le compilateur n'avertit pas que la variable n'est pas initialisée.

Print(...) peut ne pas vous avertir comme si le paramètre était passé par une référence non constante

int f( int& i ) { return i; }
void OnStart()
{
        int i;  
        f( i ); //нормально
}
 
A100:

Si les boucles sont les mêmes, alors le comportement du compilateur devrait être le même, et il est différent. C'est là que réside l'erreur. Vous avez expliqué pourquoi il y a un avertissement dans le cas (1), puis vous expliquez pourquoi il n'y en a pas dans le cas (2) ? Qu'est-ce qui a changé en principe ? Et puis, si une variable non initialisée est utilisée, pourquoi le résultat final est-il correct lors de l'exécution du code ?

Il existe une telle science - la logique. Si A et B sont identiques et que A est rouge, B doit aussi être rouge, et non vert.

Je n'ai pas étudié la programmation, je ne peux que spéculer logiquement, comme Vassili Ivanovitch et Petka ont spéculé sur la logique.

Dans le premier cas, la chaîne entière est exécutée

for ( int i = 0, j; i < 10; i = j )

et ici la variable j n'est pas initialisée, mais sa valeur est assignée à la variable i

Dans le second cas, même si la variable j n'est pas initialisée, dans la ligne suivante où elle est utilisée, ce n'est pas sa valeur qui est assignée, mais sa valeur. En d'autres termes, la variable j est initialisée avec la valeur de la variable i.

Voici une variante qui ne comporte pas non plus d'avertissements

  for(int i = 0, j; i < 10; j = i)
   {
    j = i+1;
   }
 
Alexey Viktorov:

Je n'ai pas étudié pour être un programmeur, je ne peux que spéculer logiquement, comme Vassili Ivanovitch et Petka ont spéculé sur la logique.

Dans le premier cas, la chaîne entière est exécutée

et ici la variable j n'est pas initialisée, mais sa valeur est assignée à la variable i

Et qui l'a étudié ? Je pense que la plupart des gens ici (comme moi) sont autodidactes.

Vous devez étudier l'opérateur de boucle for pour comprendre la séquence des opérations. Dans (1), la valeur de i+1 est attribuée à la variable j.

j = i+1

avant qu'il n'apparaisse à droite de l'opérateur d'affectation

i = j
 
Valeriy Yastremskiy:

Les variables globales semblent être initialisées à zéro, mais le corps de la fonction a rencontré des initialisations différentes lors du premier passage.
J'essaie toujours d'initialiser avant l'utilisation. Bien que je sois d'accord, le comportement doit être sans ambiguïté.

Et une autre déclaration dans le corps de la boucle, entre parenthèses, rend la variable locale à la boucle. Les docteurs ne l'ont pas.

Oui, j'initialise toujours les variables aussi, c'est comme deux fois deux,je devrais toujours m'en souvenir.
C'est le langage C qui m'a mis ça dans la tête))
Donc cet exemple de boucle avec une variable non initialisée est une mauvaise pratique.

 
Roman:

Oui, j'initialise toujours les variables aussi, c'est comme deux fois deux,il faut toujours s'en souvenir.
C'est le langage C qui m'a mis ça dans la tête))
Donc cet exemple de boucle avec une variable non initialisée est une mauvaise pratique.

Vous devez l'initialiser, mais seulement avec une valeur significative. Il n'y a pas de valeur de ce type dans l'exemple ci-dessus, ce n'est donc pas une mauvaise pratique et c'est le seul moyen possible. Sinon, il y aurait une double initialisation

int f( int i ) { /*вычисления*/ }
void g( int k )
{
        for ( int i = 0, j; i < k; i = j )
        {
                j = f( i );
                /*вычисления*/
        }
}
 
A100:

Initialiser, mais seulement avec une valeur significative. Il n'y a pas de telle valeur dans l'exemple ci-dessus, donc la pratique n'est pas mauvaise, c'est la seule possible. Sinon, il y aurait une double initialisation

Qu'est-ce que cela changerait si vous initialisiez

int f( int i ) { /*вычисления*/ }
void g( int k )
{
   for ( int i=0, j=0; i < k; i = j )
   {
      j = f( i );
      /*вычисления*/
   }
}       
 
Roman:

Que changerait-il s'il était initialisé avec j=333 ?

Et pourquoi par zéro et non j=333 disons ? Il s'agit d'une initialisation sans signification qui peut cacher une erreur difficile à trouver.

 
A100:

Pourquoi zéro et pas 333, disons ? Il s'agit d'une initialisation sans signification qui peut cacher une erreur difficile à détecter.

Si vous avez besoin d'attraper une erreur de cette valeur, eh bien, initialisez-la avec 333 ))
C'est juste une valeur de départ.

 
Roman:

Si vous avez besoin d'attraper une erreur de cette valeur, il faut l'initialiser avec 333 ))
C'est seulement une valeur de départ.

C'est vrai, c'est un bug. Donc, soit nous donnons un avertissement sur l'assignation de variables non initialisées dans tous les cas, soit nous ne le faisons pas, et nous les initialisons avec un zéro par défaut par exemple, dans le langage dans tous les mêmes cas.