C: conversion de type lors du passage d'un argument sur un appel de fonction
À partir Du Langage de Programmation C 2e Édition:
Depuis un argument d'un appel de fonction est une expression, les conversions de type également avoir lieu lorsque les arguments sont passés à la fonction. En l'absence d'un prototype de fonction, char et short devenir int et float devient double.
En lisant le texte, j'obtiens une impression qu'à moins de spécifier explicitement le type d'argument en utilisant la technique de fonte ou d'un prototype de fonction, les arguments de la fonction est toujours passé comme passé comme int ou double.
Afin de vérifier mon hypothèse, j'ai compilé le code suivant:
#include <stdio.h>
main()
{
unsigned char c = 'Z';
float number = 3.14f;
function_call(c, number);
}
void function_call(char c, float f)
{
}
Après la compilation j'obtiens les avertissements suivants:
typeconversion.c:11: avertissement: conflicting types for ‘function_call’
typeconversion.c:7: avertissement: précédente déclaration implicite de " function_call’ était ici
Je suppose que c et le nombre ont été à la fois converti en int et double sur l'appel de la fonction, et ont ensuite été convertis en arrière à l'omble chevalier et de flotter. Est-ce ce qui s'est réellement passé?
source d'informationauteur Midnight Blue
Vous devez vous connecter pour publier un commentaire.
Les castes sont hors de propos, c'est l' (éventuellement implicite) prototype qui compte.
Quand le livre dit "un argument d'un appel de fonction est une expression" cela signifie que le même type de promotion règles s'appliquent. Il pourrait être plus facile à comprendre si vous pensez à un argument de fonction implicite d'affectation à la variable spécifiée dans le prototype de fonction. par exemple, dans l'appel à
foo()
- dessus il y a un impliciteshort s = c
.C'est pourquoi jette n'a pas d'importance. Considérons l'extrait de code suivant:
Ici la valeur de c est promu premier à
short
(explicitement) puis àint
(implicitement). La valeur dei
sera toujours unint
.Comme pour
char
etshort
devenirint
etfloat
devenirdouble
qui désigne les types par défaut implicite des prototypes de fonction. Lorsque le compilateur voit un appel à une fonction avant d'avoir vu un prototype ou de la définition de la fonction qui génère un prototype automatiquement. La valeur par défaut estint
pour les valeurs entières etdouble
pour les valeurs à virgule flottante.Si l'éventuelle déclaration de fonction ne correspond pas à l'implicite prototype, vous obtiendrez des mises en garde.
Vous avez l'idée générale de ce qui est faux, mais pas exactement.
Ce qui s'est passé, c'est que lorsque vous avez écrit
Le compilateur a vu que vous étiez en appelant une fonction qu'il n'avait pas encore vu, et a donc dû décider que sa signature devrait être. Basé sur la promotion de la règle que vous avez cité précédemment, il est promu char, int et float en double et a décidé que la signature est
Puis quand il voit
il interprète cela comme une signature pour une autre fonction avec le même nom, ce qui n'est pas autorisé dans C. C'est exactement la même erreur que si vous avez un prototype d'une fonction différente de la façon dont vous définissent en fait, c'est juste que dans ce cas, le prototype est implicitement généré par le compilateur.
Donc, c'est cette règle qui est à l'origine du problème, mais l'erreur n'a rien à voir avec la réalité de la conversion de valeurs de retour et vient entre les types.
Le compilateur se plaint qu'il a supposé function_call est un int retour de fonction, comme indiqué par la norme, et puis vous dire qu'il est une fonction void. Le compilateur ne se soucient pas des arguments, sauf si vous explicitement les déclarant être différentes de la fonction réelle. Vous pouvez la passer sans arguments, et il ne faudra pas se plaindre.
Vous devez toujours déclarer vos fonctions, parce que cette erreur ne soit pas détectée si la fonction est dans d'autres modules. Si la fonction doit retourner n'importe quel type qui pourrait être plus grande que int comme void* ou long, le cast en int en l'appelant la fonction sera le plus susceptible de le tronquer, vous laissant avec un bug bizarre.
Tout le monde a oublié une chose. En ISO C un ISO-syntaxe prototype remplace par défaut de l'argument de promotion.
Et dans ce cas, le compilateur est autorisé pour générer un code différent (!) basée sur le style de la définition. Cela vous arrive de K&R de compatibilité, mais vous ne pouvez pas toujours faire appel à entre les niveaux de langue, à moins que vous avez écrit le code ISO K&R s'attend à ce ou modifié le K&R code pour voir l'ISO prototypes.
Essayer avec cc -S -O ...