# L'hexadécimal en C

**URL:** <https://www.debian-fr.org/t/lhexadecimal-en-c/53137>\
**Category:** Programmation\
**Created:** [Février 21, 2016, 11:55 UTC](https://www.debian-fr.org/t/lhexadecimal-en-c/53137 "2016-02-21T11:55:27Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Cluxter](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/c/13edae/32.png) [@Cluxter](https://www.debian-fr.org/u/Cluxter)\
**Post date:** [Février 21, 2016, 11:55 UTC](https://www.debian-fr.org/t/lhexadecimal-en-c/53137/1 "2016-02-21T11:55:27Z")

</div>

Bonjour à tous

Je me mets enfin sérieusement à l’étude du C à l’aide de l’ouvrage de référence qu’il n’est plus la peine de présenter, “Le langage C” de Ritchie et Kernighan.

Voici un programme que j’ai écris :

[code]#include \<stdio.h\>  
#include \<stdlib.h\>

int main()  
{  
printf("%f %o %x", 123.45, 9, 17.3);

```
return 0;

```

}[/code]

Lorsque je l’exécute une première fois, j’obtiens :

```auto

```

Et la seconde fois :

```auto

```

Bien évidemment j’obtiens quelque chose d’incohérent pour le 3ème argument. Mais j’aimerais comprendre pourquoi j’obtiens une valeur aléatoire ? D’où provient-elle ? Est-ce que cela pourrait introduire une faille de sécurité ?

Merci à vous

---

<div class="post-metadata">

**Author:** ![Eho](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/e/eb8c5e/32.png) [@Eho](https://www.debian-fr.org/u/Eho)\
**Post date:** [Février 21, 2016, 11:55 UTC](https://www.debian-fr.org/t/lhexadecimal-en-c/53137/2 "2016-02-21T11:55:28Z")

</div>

Au hasard ça doit venir de la représentation des flottants, mais chez moi ça fait le même résultat (apparement)

```auto

```

Compile en activant les avertissements et tu comprendras ton erreur

`gcc main.c -Wall -Wextra -pedantic
main.c: In function ‘main’:
main.c:6:5: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 4 has type ‘double’ [-Wformat]`

---

<div class="post-metadata">

**Author:** ![Cluxter](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/c/13edae/32.png) [@Cluxter](https://www.debian-fr.org/u/Cluxter)\
**Post date:** [Février 21, 2016, 11:55 UTC](https://www.debian-fr.org/t/lhexadecimal-en-c/53137/3 "2016-02-21T11:55:28Z")

</div>

> [@](#):
>
> Compile en activant les avertissements et tu comprendras ton erreur

Oui je l’ai fait et je m’attendais avant même de compiler le programme à avoir au moins un avertissement, si ce n’est une erreur.

Ce que j’aimerais comprendre ce n’est pas pourquoi j’ai cette erreur (ça je le sais) mais comment ça fonctionne derrière. D’où vient cette valeur exactement ? Pourquoi j’ai une valeur aléatoire plutôt qu’une valeur fixe par exemple ?

---

<div class="post-metadata">

**Author:** ![panthere](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/p/5daacb/32.png) [@panthere](https://www.debian-fr.org/u/panthere)\
**Post date:** [Février 21, 2016, 11:55 UTC](https://www.debian-fr.org/t/lhexadecimal-en-c/53137/4 "2016-02-21T11:55:29Z")

</div>

je fait pas du C , mai du C++, mai en principe on initialise une variable et son type

en gros:  
int M;  
est different de  
int M = 0;

car le premier contien ce qu’il y a en memoire, l’autre y a déjà écrit une valeur.  
vu que tu écris directement dans le printf je sai pas si la déclaration ce passe de la meme manière

---

<div class="post-metadata">

**Author:** ![Eho](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/e/eb8c5e/32.png) [@Eho](https://www.debian-fr.org/u/Eho)\
**Post date:** [Février 21, 2016, 11:55 UTC](https://www.debian-fr.org/t/lhexadecimal-en-c/53137/5 "2016-02-21T11:55:30Z")

</div>

J’ai toujours la même sortie sur mon ordi (gcc 4.7) mais sur un autre ordi (gcc 4.6) j’ai effectivement des valeurs qui changent.

Soit c’est un problème d’arrondi (ça me paraît bizzare) soit c’est un problème de valeur non initialisée (ça me paraît bizzare aussi) soit … ?

Tu peux toujours regarder le code assembleur:  
gcc 4.7

`$ gdb -q a.out
Reading symbols from /media/Unstable/a.out...done.
(gdb) disas main
Dump of assembler code for function main:
   0x000000000040050c <+0>: push %rbp
   0x000000000040050d <+1>: mov %rsp,%rbp
   0x0000000000400510 <+4>: sub $0x10,%rsp
   0x0000000000400514 <+8>: movabs $0x40314ccccccccccd,%rdx
   0x000000000040051e <+18>: movabs $0x405edccccccccccd,%rax
   0x0000000000400528 <+28>: mov %rdx,-0x8(%rbp)
   0x000000000040052c <+32>: movsd -0x8(%rbp),%xmm1
   0x0000000000400531 <+37>: mov $0x9,%esi
   0x0000000000400536 <+42>: mov %rax,-0x8(%rbp)
   0x000000000040053a <+46>: movsd -0x8(%rbp),%xmm0
   0x000000000040053f <+51>: mov $0x40060c,%edi
   0x0000000000400544 <+56>: mov $0x2,%eax
   0x0000000000400549 <+61>: callq 0x4003e0 <printf@plt>
   0x000000000040054e <+66>: mov $0x0,%eax
   0x0000000000400553 <+71>: leaveq 
   0x0000000000400554 <+72>: retq   
End of assembler dump.`  
gcc 4.6

`$ gdb -q a.out 
Reading symbols from /home/eo/a.out...done.
(gdb) disas
No frame selected.
(gdb) disas main
Dump of assembler code for function main:
   0x00000000004004e4 <+0>: push %rbp
   0x00000000004004e5 <+1>: mov %rsp,%rbp
   0x00000000004004e8 <+4>: mov $0x400610,%eax
   0x00000000004004ed <+9>: movsd 0x12b(%rip),%xmm1 # 0x400620
   0x00000000004004f5 <+17>: movsd 0x12b(%rip),%xmm0 # 0x400628
   0x00000000004004fd <+25>: mov $0x9,%esi
   0x0000000000400502 <+30>: mov %rax,%rdi
   0x0000000000400505 <+33>: mov $0x2,%eax
   0x000000000040050a <+38>: callq 0x4003e0 <printf@plt>
   0x000000000040050f <+43>: mov $0x0,%eax
   0x0000000000400514 <+48>: pop %rbp
   0x0000000000400515 <+49>: retq   
End of assembler dump.`

PS: si tu veux une erreur

`$ gcc main.c -Wall -Wextra -pedantic -Werror
main.c: In function ‘main’:
main.c:6:5: error: format ‘%x’ expects argument of type ‘unsigned int’, but argument 4 has type ‘double’ [-Werror=format]
cc1: all warnings being treated as errors
`

---

<div class="post-metadata">

**Author:** ![Cluxter](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/c/13edae/32.png) [@Cluxter](https://www.debian-fr.org/u/Cluxter)\
**Post date:** [Février 21, 2016, 11:55 UTC](https://www.debian-fr.org/t/lhexadecimal-en-c/53137/6 "2016-02-21T11:55:30Z")

</div>

[quote]Tu peux toujours regarder le code assembleur

$ gdb -q a.out[/quote]  
Voilà qui devrait m’aider pour beaucoup de choses à l’avenir !!  
Merci pour cette aide, ça devrait me permettre de comprendre comment ça fonctionne ![:023](https://www.debian-fr.org/uploads/default/original/1X/3c587556c0cc11389317c03a60788d77ceebd307.gif "OK")

---

<div class="post-metadata">

**Author:** ![Eho](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/e/eb8c5e/32.png) [@Eho](https://www.debian-fr.org/u/Eho)\
**Post date:** [Février 21, 2016, 11:55 UTC](https://www.debian-fr.org/t/lhexadecimal-en-c/53137/7 "2016-02-21T11:55:30Z")

</div>

(C n’est pas fortement typé, mais) peut être qu’un cast explicite donne quelque chose de “correct”.

---

<div class="post-metadata">

**Author:** ![Taurre](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/t/f04885/32.png) [@Taurre](https://www.debian-fr.org/u/Taurre)\
**Post date:** [Février 21, 2016, 12:04 UTC](https://www.debian-fr.org/t/lhexadecimal-en-c/53137/8 "2016-02-21T12:04:52Z")

</div>

Salut,

Tu as effectué le test sur une machine de la famille amd64?  
Si oui, c’est normal, cela est dû à la convention d’appel utilisée sur ce type d’architecture. Sans trop entrer dans les détails, il faut savoir que sous une architecture amd64, les arguments sont majoritairement passés via les registres et non via la pile. Dans le cas d’une fonction à nombre variable d’argument (comme printf), l’ensemble des valeurs des registres utilisés pour passer les arguments (à l’exception de ceux déjà pris pour des arguments non optionnels) sont stockés dans une zone de sauvegarde divisée en deux: les arguments de type entier et pointeur d’un côté et ceux de type flottant de l’autre.

Dans ton cas que se passe-t-il? Tu vas bien chercher 9 et 123.45 dans leurs parties respectives, mais tu vas chercher 17.3 dans la partie entière alors qu’il est dans la partie flottante. Résultat, tu récupères la valeur d’un registre qui n’a pas été utilisé pour stocker un argument optionnel. Étant donné que la valeur d’un registre change très souvent, cela explique que tu obtiennes un résultat différent d’une exécution à l’autre de ton programme.

Pour les téméraires, l’[abi](http://www.x86-64.org/documentation/abi.pdf) de l’architecture amd64 ![:mrgreen:](https://www.debian-fr.org/uploads/default/original/1X/cc83e9b583138e48ff45f96609046b06d06c7f9d.gif "Mr. Green")
