Promotion entiere
Le
candide
Bonjour,
D'abord, un point de vocabulaire : en français, parle-t-on de "promotion
entière" ou de "promotion intégrale" ?
D'autre part, le passage de la norme qui parle de cette question est, à
mon sens, trop fortement obscurci par une note de bas de page. Plus
précisément, il est dit :
8<--
6.3.1.1p2
()If an int can represent all values of the original type, the value
is converted to an int; otherwise, it is converted to an unsigned int.
These are called the integer promotions.(48)
La note de bas de page :
(48) -- The integer promotions are applied only: as part of the usual
arithmetic conversions, to certain argument expressions, to the operands
of the unary +, -, and ~ operators, and to both operands of the
shift operators, as specified by their respective subclauses.
>8--
Si j'ai bien lu la norme, les conversions arithmétiques usuelles
s'appliquent uniquement à des opérateurs binaires et il faut regarder
dans la norme au cas par cas lesquels sont concernés.
Concernant les "argument expressions", bon je suppose les expressions
qui sont arguments de fonctions, lesquelles sont concernées ? K&R parle
de ceci :
8<--
In the absence of a function prototype, char and short become int,
>8--
c'est à ça qu'il est fait allusion ?
Je crois que beaucoup de livres de C n'ont pas tenu compte de cette note
de pas de page. Par exemple, dans le livre de Delannoy, je lis (page
78, §3.1) :
8<--
"Aucun opérateur n'accepte d'opérandes de type char ou short."
>8--
C'est vrai ou pas ?
De même dans le livre de Braquelaire, je lis :
8<--
"Lors de l'évaluation d'une expression, un opérande d'un type intégral
caractère, entier court, champ de bits ou énumération est converti dans
le type int ou dans le type unsigned int si le type int n'est pas assez
grand pour représenter toutes les valeurs de son type. Cette conversion
s'appelle promotion intégrale. "
>8--
mais aucune allusion à la note de bas de page.
Plus généralement, avez-vous des exemples simples où la promotion
entière ne s'applique pas ?
Merci
D'abord, un point de vocabulaire : en français, parle-t-on de "promotion
entière" ou de "promotion intégrale" ?
D'autre part, le passage de la norme qui parle de cette question est, à
mon sens, trop fortement obscurci par une note de bas de page. Plus
précisément, il est dit :
8<--
6.3.1.1p2
()If an int can represent all values of the original type, the value
is converted to an int; otherwise, it is converted to an unsigned int.
These are called the integer promotions.(48)
La note de bas de page :
(48) -- The integer promotions are applied only: as part of the usual
arithmetic conversions, to certain argument expressions, to the operands
of the unary +, -, and ~ operators, and to both operands of the
shift operators, as specified by their respective subclauses.
>8--
Si j'ai bien lu la norme, les conversions arithmétiques usuelles
s'appliquent uniquement à des opérateurs binaires et il faut regarder
dans la norme au cas par cas lesquels sont concernés.
Concernant les "argument expressions", bon je suppose les expressions
qui sont arguments de fonctions, lesquelles sont concernées ? K&R parle
de ceci :
8<--
In the absence of a function prototype, char and short become int,
>8--
c'est à ça qu'il est fait allusion ?
Je crois que beaucoup de livres de C n'ont pas tenu compte de cette note
de pas de page. Par exemple, dans le livre de Delannoy, je lis (page
78, §3.1) :
8<--
"Aucun opérateur n'accepte d'opérandes de type char ou short."
>8--
C'est vrai ou pas ?
De même dans le livre de Braquelaire, je lis :
8<--
"Lors de l'évaluation d'une expression, un opérande d'un type intégral
caractère, entier court, champ de bits ou énumération est converti dans
le type int ou dans le type unsigned int si le type int n'est pas assez
grand pour représenter toutes les valeurs de son type. Cette conversion
s'appelle promotion intégrale. "
>8--
mais aucune allusion à la note de bas de page.
Plus généralement, avez-vous des exemples simples où la promotion
entière ne s'applique pas ?
Merci

Poser une question


Ca ne me surprend pas de Delannoy, que je n'aime pas trop.
Ces deux bouquins font reference au C pre-norme, dit aussi
C Kernighan & Richie, dans lequel les regles de promotion sont beaucoup
plus simples: les calculs se font systematiquement sur des int ou des
double, il n'y a pas d'arithmetique sur des short ou des float.
La norme explicite la possibilite d'avoir le calcul sur les float, et
reste tres evasive sur les entiers. Elle explique qu'on peut avoir
conversion vers des int, ou assimiles, mais ca n'a vraiment pas l'air
d'etre obligatoire.
Ca ressemble fort a la possibilite de permettre a un compilateur travaillant
dans un environnement un peu specifique de faire ses calculs directement
sur des short, par exemple...
Typiquement, un gcc sur i386 va faire ses calculs sur des short si on lui
en laisse la possibilite.
Par exemple:
struct point {
short x, y;
};
short f(struct point *p)
{
return p->x + p->y;
}
se compile en:
f:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %edx
movw 2(%edx), %ax
addw (%edx), %ax
cwtl
leave
ret
Le plus naif
short f(short a, short b)
donne un calcul sur des mots de 32 bits, lie a l'ABI standard de mon
systeme, qui meme en presence de prototypes, passe les short par mots
de 32 bits sur la pile...
C'est d'ailleurs nécessaire pour le support IEEE 754, car un calcul
en double précision puis un arrondi en simple précision (float) ne
donne pas toujours le même résultat qu'un calcul direct en simple
précision (effet du double arrondi).
--
Vincent Lefèvre 100% accessible validated (X)HTML - Blog: Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)
En français, « promotion intégrale » va faire penser à la promotion de la
totalité du sujet (cf. intégralité), donc perdre la relation avec le mot «
entier ».
Maintenant, dans le jargon des spécialiste du langage C, j'imagine que tu
vas trouver les deux.
Une note de bas de page a un caractère moins contraignant que le texte de la
norme (c'est comme comparer une explication donnée par un code Dalloz avec
le texte d'une loi) ; donc si ce n'est pas clair _avec_ la note, tu fais
abstraction de la note.
Par ailleurs, et même si c'est moins facile à consulter que le snotes de bas
de page, il est bon de lire aussi le paragraphe correspondant du Rationale.
En l'occurence tu vas avoir plus que ce que tu ne cherches (par exemple, une
discussion sur la différence entre préservation de la valeur ou préservation
de la qualité d'être signé).
Raison pour laquelle la note cite explicitement les autres cas (en dehors
des conversions usuelles) où les promotions entières vont être appliquées.
Si tu as un meilleur texte à proposer (en anglais) pour la note, tu peux
lancer une discussion sur comp.std.c ; Larry Jones (le type qui écrit le
texte de la norme) suit ce groupe, et on est dans le bon timing pour que ce
genre de corrections (dites « éditoriales ») soient prises en compte dans la
prochaine moûture.
Un coseil : suit un peu le groupe avant de rentrer dedans de plein pied : il
faut un peu d'expérience (et la lecture assidue des archives) pour savoir si
tel ou tel intervenant est un trolleur fou ou quelqu'un de respecté ; et il
arrive assez souvent que la première réponse y compris émanent d'un gars
sérieux soit faite sans trop réfléchir, surtout si la question ou le style
ou l'auteur n'est pas habituelle (et nous autres Français avons semble-t-il
une manière assez différente d'aborder le texte normatif par rapport aux
Américains).
Il y a deux pages de texte dans 6.5.2.2 qui sont quasiment exclusivement
dédiées à ce sujet, donc je ne vais pas faire un long exposé (avec le risque
élevé de me planter :-B).
En fait, beaucoup de livres de C cherchent à rendre accessible un sujet ; de
ce fait les auteurs peuvent choisir des raccourcis si cela rend leur propos
plus clair, peut-être au détriment de certains cas particuliers. La norme de
son côté n'a pas cet objectif, elle cherche à définir un contrat (entre
l'implémenteur du compilateur et le programmeur) en laissant le moins de
marge possible aux ambiguïtés.
Quand tu lis « Aucun » ou n'importe quel mot définitif de cet acabit sur un
sujet qui par ailleurs paraît complexe, il y a deux possibilités avec des
probabilités très inégales :
- celui qui présente le sujet de manière très complexe est un nul ou
cherche délibérement à emberlificoter (cas typique du texte d'un brevet) ;
- le jugement définitif est à l'emporte-pièce.
Bin non. Par exemple, dans
char i; int j = sizeof i;
l'opérande (ici i) de l'opérateur sizeof n'est pas promu, et reste de type
char. Et heureusement, parce que sinon on voit mal l'intérêt de l'opérateur
sizeof dans le cas général (dans ce cas précis par contre, cela peut avoir
une utilité que n'a pas le code que j'ai écrit ;-) ).
Appel de fonction (avec prototypes de types char ou short), conversions, et
affectation à un char ou un short (évidemment !)
Il est aussi des cas où la promotion ne s'applique pas mais cela n'a aucun
effet (visible) : par exemple, quand on ajoute un entier à un pointeur, il
n'y a pas dans la norme de promotion sur l'entier, mais il est de toutes
manières impossible de voir l'effet d'une éventuelle promotion ; idem pour
l'opérateur ! appliqué à un char ou un short.
Après cela, que le compilateur fasse (ou pas) une extension de signe pour
utiliser tel ou tel mode d'adressage ou instruction du processeur, ici tout
est libre, car le seul le résultat compte !
Antoine
;)
Justement, une des choses les plus difficiles du C je trouve est (je
parle en tant que post-débutant) de comprendre tout ce qui tient aux
conversions et aux cast.
Tiens oui, en effet. J'espère que la norme explique ça quelque part (je
dis ça parce que je ne vois pas ce point dans le paragraphe 6.5.3.4 The
sizeof operator).
Quand on parle de promotion (dans tous les langages avec des conversions
implicites et pas seulement en C) d'une variable dans un autre type, il
ne s'agit pas de la conversion de la variable elle-même mais de la
création, par le compilateur, d'une variable temporaire qui contiendra
le résultat de la promotion (comme pour le passage d'arguments par valeur).
Attention aux confusions !!