Warning bizarre

Résolu
Signaler
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Modérateur
Dernière intervention
22 août 2010
-
Messages postés
20
Date d'inscription
lundi 17 janvier 2005
Statut
Membre
Dernière intervention
13 mars 2005
-
Salut



Je ne sais pas si c'est moi qui délires, mais je ne comprends pas
pourquoi le code suivant génère un warning variable "locale 'd'
utilisée sans avoir été initialisée":



int main()

{

int d = 0, p;

p = *((int*)(&d + 1));

}

11 réponses

Messages postés
21041
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
30
Il aurait du être initialisé mais j'ai vérifié le listing, il ne l'est effectivement pas.
Comme quoi c'est pas toujours bon de croire que le compilo fera exact ce qui est écrit, les messages d'alertes sont plus surs.

ciao...
BruNews, MVP VC++
Messages postés
21041
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
30
p = *((int*)(((BYTE*)&d) + 1));
ne sort plus de warning mais est-ce bien ce que tu veux, lire un 32 bits a une adresse non alignee ???

ciao...
BruNews, MVP VC++
Messages postés
224
Date d'inscription
mardi 12 août 2003
Statut
Membre
Dernière intervention
18 octobre 2010

Bizard car le warning disparait si d est globale.
Sinon ca serais pas plutot p = *((int*)(((BYTE*)&d) + 4)); ?
Messages postés
21041
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
30
depend justement de ce qu'il veut, +4 lira un int correctement aligne 4 octets plus haut en memoire.

ciao...
BruNews, MVP VC++
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Modérateur
Dernière intervention
22 août 2010
10
Même avec +4 on a un warning...

Mais il me semble que &d+1 donne un adresse alignée sur 4 octets
puisque d est int. C'est comme quand on incrémente un int*, en fait ca
l'incrémente de 4.
Messages postés
21041
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
30
"il me semble" voila bien un des mots qui n'ont rien a faire en terme de dev. Il suffit de controler la sortie asm du compilo pour voir qu'il a obéi au doigt et à l'oeil:
mov ecx, dword ptr[esp+41]
t'es parti ici pour au moins 100 cycles au lieu de 1 normal avec le rattrapage logiciel que fera le systeme.

ciao...
BruNews, MVP VC++
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Modérateur
Dernière intervention
22 août 2010
10
C'est vrai, j'y pense pas assez souvent.

Mais nous n'avons pas la même sortie, moi il ne donne rien de ce type, voila ce que j'ai (sans /Oy):



; 4 : int p = *((int*)(&d + 1));

mov eax, DWORD PTR _d$[ebp+4]

mov DWORD PTR _p$[ebp], eax
Messages postés
21041
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
30
Pour sur qu'on n'a pas la meme, j'ai pris la sortie sans warning:
p = *((int*)(((BYTE*)&d) + 1));
Fais gaffe avec ces conversions implicites en arithmetique pointeur, si tu veux le dword suivant je te conseille plutot:
p = *((int*)(((BYTE*)&d) + 4));
tu peux ainsi relire explicitement ce que tu voulais.

ciao...
BruNews, MVP VC++
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Modérateur
Dernière intervention
22 août 2010
10
OK, mais pour revenir au problème de départ, d'où vient ce warning? Il n'a pas du tout de sens puisque d est initialisée...
Messages postés
20
Date d'inscription
lundi 17 janvier 2005
Statut
Membre
Dernière intervention
13 mars 2005

Salut,



[***]$ cat > tmp.c

int main()

{

int d = 0, p;

p = *((int*)(&d + 1));

}

[***]$ gcc tmp.c

[***]$ gcc -Wall tmp.c

tmp.c: In function `main':

tmp.c:5: attention : contrôle a atteint la fin non void de la fonction



gcc m'a jamais vraiment pris la tête. Adopte.
Messages postés
20
Date d'inscription
lundi 17 janvier 2005
Statut
Membre
Dernière intervention
13 mars 2005

Et j'oubliais :


[***]$ gcc -O3 tmp.c



pushl %ebp

movl %esp, %ebp

subl $8, %esp

andl $-16, %esp

subl $16, %esp

leave

ret