Programmation C++/Conventions d'appel
Convention d'appel[modifier | modifier le wikicode]
Une convention d'appel à une fonction définit la manière d'appeler une fonction. La manière varie selon le langage de programmation, le compilateur, et parfois l'architecture du processeur cible.
En C++ la convention d'appel définit les points suivants :
- l'ordre d'empilage des paramètres (à partir du premier, ou du dernier),
- passage de certains paramètres dans les registres,
- appel avec une adresse longue ou courte (selon la localisation en mémoire de la fonction),
- désempilage des paramètres effectué par la fonction appelée ou le code appelant,
- méthode de récupération de la valeur retournée.
Pour l'avant dernier point, le désempilage des paramètres est toujours effectué par le code appelant lorsque la fonction a un nombre variable d'arguments, car seul le code appelant connait assuremment le nombre de paramètres qu'il a empilé.
Spécifier la convention d'appel[modifier | modifier le wikicode]
La convention d'appel est spécifiée juste avant le nom de la fonction. Parmi les conventions d'appel possibles :
__cdecl
: Convention d'appel par défaut du C et du C++ quand la fonction est définie en dehors de toute classe, ou comporte un nombre variable d'arguments,__stdcall
: Convention d'appel utilisé par l'API Windows,__fastcall
: Passage de certains paramètres dans les registres,thiscall
: Convention d'appel utilisée implicitement par défaut par les fonctions définies dans une classe car il ajoute un paramètre supplémentaire : la référence à l'objetthis
. Ce mot clé ne peut être utilisé.pascal
:vectorcall
:
Différences entre les conventions d'appel[modifier | modifier le wikicode]
Convention | Paramètres dans les registres | Empilage des paramètres | Dépilage des paramètres |
---|---|---|---|
__cdecl
|
aucun | de droite à gauche | par le code appelant |
__stdcall
|
aucun | de droite à gauche | par la fonction appelée |
__fastcall
|
les 2 premiers arguments de taille inférieure à 32 bits | de droite à gauche | par la fonction appelée |
thiscall
|
aucun | de droite à gauche | par la fonction appelée |
Si la convention d'appel utilisée par le code appelant ne correspond pas à celui de la fonction appelée, la fonction ne comprend pas l'appel effectué et peut causer des dégats.
Nommage des fonctions[modifier | modifier le wikicode]
Pour éviter des problèmes lors de l'édition de liens avec les librairies externes (extension .dll
sous Windows, .so
sous Unix/Linux), le compilateur nomme les fonctions selon les critères suivants :
- Nom de la fonction,
- Type des arguments,
- Convention d'appel utilisée,
- Type des exceptions lancées,
- Nom de la classe où se situe la fonction.
Chaque compilateur utilise un nommage différent.
Par exemple, pour la fonction void h(int, char)
le nom généré dépend du compilateur :
- GCC 3+, Clang 1+ :
_Z1hic
- GCC 2.9x :
h__Fic
- Microsoft Visual C++ :
?h@@YAXHD@Z
- Borland C++ :
@h$qizc
- SunPro CC :
__1cBh6F_v_
- ...
Il est donc difficile d'utiliser une librairie qui n'a pas été compilée avec le même compilateur que l'application l'utilisant.
Liens[modifier | modifier le wikicode]
- (anglais) Calling Convention
- (anglais) X86 Calling Convention
- (anglais) Calling Conventions in Microsoft Visual C++
- (anglais) Name mangling