Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

sizeof(short)

34 réponses
Avatar
candide
Bonjour,


J'ai lu ici même que : sizeof (short) <= sizeof (int) et de même que
sizeof (int) < sizeof (long).

J'ai beau lire et relire la Norme, je ne vois pas où cela est garanti.

Quelqu'un peut-il préciser ? Merci

10 réponses

1 2 3 4
Avatar
Pierre Maurette
candide, le 21/07/2009 a écrit :
Bonjour,


J'ai lu ici même que : sizeof (short) <= sizeof (int) et de même que
sizeof (int) < sizeof (long).



Je ne pense pas que le int soit obligatoirement *strictement* moins
large que le long. Simplement s'il y a égalité, ça impose que int soit
sur au moins 32 bits, INT_MAX == LONG_MAX >= 0x7FFFFFF

J'ai beau lire et relire la Norme, je ne vois pas où cela est garanti.

Quelqu'un peut-il préciser ? Merci



Il me semble que c'était explicite dans la version précédente de la
norme C, à moins que ce ne soit dans celle de C++. Dans la C99 que j'ai
sous les yeux, si on veut prouver, on doit pouvoir passer par 6.3.1.1
(définition de /integer conversion rank/), en particulier:
<CIT>
- The rank of a signed integer type shall be greater than the rank of
any signed integer type with less precision.
- The rank of long long int shall be greater than the rank of long int,
which shall be greater than the rank of int, which shall be greater
than the rank of short int, which shall be greater than the rank of
signed char.
</CIT>
Ensuite on fait la relation entre le /rank/ et le /range/ en 6.2.5.8,
puis on regarde la représentation des types en 6.2.6 et la définition
de l'opérateur sizeof.


--
Pierre Maurette
Avatar
zwim
Le Tue, 21 Jul 2009 07:11:07 +0200
Pierre Maurette a écrit
candide, le 21/07/2009 a écrit :
Bonjour,


J'ai lu ici même que : sizeof (short) <= sizeof (int) et de même que
sizeof (int) < sizeof (long).



Je ne pense pas que le int soit obligatoirement *strictement* moins
large que le long. Simplement s'il y a égalité, ça impose que int soit
sur au moins 32 bits, INT_MAX == LONG_MAX >= 0x7FFFFFF

J'ai beau lire et relire la Norme, je ne vois pas où cela est garanti.

Quelqu'un peut-il préciser ? Merci



Il me semble que c'était explicite dans la version précédente de la
norme C, à moins que ce ne soit dans celle de C++. Dans la C99 que j'ai
sous les yeux, si on veut prouver, on doit pouvoir passer par 6.3.1.1
(définition de /integer conversion rank/), en particulier:
<CIT>
- The rank of a signed integer type shall be greater than the rank of
any signed integer type with less precision.
- The rank of long long int shall be greater than the rank of long int,
which shall be greater than the rank of int, which shall be greater
than the rank of short int, which shall be greater than the rank of
signed char.
</CIT>
Ensuite on fait la relation entre le /rank/ et le /range/ en 6.2.5.8,
puis on regarde la représentation des types en 6.2.6 et la définition
de l'opérateur sizeof.



Bah le compilateur fait ce qui lui chante à mon avis.

Rien à priori n'interdit que
sizeof(char)=sizeof(short)=sizeof(int)=sizeof(long)=1 et que tout ce
petit monde soit un 32 bit sur un machine 32 bits (i.e. soit
représenté par un type unique en interne).

Du moment qu'il sait caster correctement (unsigned char) 0xFFFFab en
0xab (car la norme dit UCHAR_MAX = 0xFF) et des choses de ce genre, ça
suffit.

Seules les limites min, max et umax sont imposées (dans <limits.h>),
après la taille que le compilo gère en interne c'est sa tambouille.
Tout ce qu'on lui demande c'est de savoir caster correctement et gérer
les opérations arithmétiques en concordance avec les limites imposées.

En particulier rien n'interdit qu'un short soit codé sur 128 bits et
un long sur 32 bits. Je vous l'accorde, niveau optim c'est pas
terrible, mais ça respecte la norme.

Du coup, les concepteurs ont fait rimer limits.h avec la taille
utilisée en interne pour la représentation pour plus de simplicité et
de bon sens, mais à mon avis rien n'est imposée par la norme à ce
niveau.

Je me fourvoie peut-être, mais c'est ce que je comprends de la norme.


--
zwim.
Rien n'est impossible que la mesure de la volonté humaine...
Avatar
Pierre Maurette
zwim, le 21/07/2009 a écrit :
Le Tue, 21 Jul 2009 07:11:07 +0200
Pierre Maurette a écrit
candide, le 21/07/2009 a écrit :
Bonjour,


J'ai lu ici même que : sizeof (short) <= sizeof (int) et de même que
sizeof (int) < sizeof (long).



Je ne pense pas que le int soit obligatoirement *strictement* moins
large que le long. Simplement s'il y a égalité, ça impose que int soit
sur au moins 32 bits, INT_MAX == LONG_MAX >= 0x7FFFFFF

J'ai beau lire et relire la Norme, je ne vois pas où cela est garanti.

Quelqu'un peut-il préciser ? Merci



Il me semble que c'était explicite dans la version précédente de la
norme C, à moins que ce ne soit dans celle de C++. Dans la C99 que j'ai
sous les yeux, si on veut prouver, on doit pouvoir passer par 6.3.1.1
(définition de /integer conversion rank/), en particulier:
<CIT>
- The rank of a signed integer type shall be greater than the rank of
any signed integer type with less precision.
- The rank of long long int shall be greater than the rank of long int,
which shall be greater than the rank of int, which shall be greater
than the rank of short int, which shall be greater than the rank of
signed char.
</CIT>
Ensuite on fait la relation entre le /rank/ et le /range/ en 6.2.5.8,
puis on regarde la représentation des types en 6.2.6 et la définition
de l'opérateur sizeof.



Bah le compilateur fait ce qui lui chante à mon avis.



Pas tout à fait si on parle d'un compilateur respectant une norme.

Rien à priori n'interdit que
sizeof(char)=sizeof(short)=sizeof(int)=sizeof(long)=1 et que tout ce
petit monde soit un 32 bit sur un machine 32 bits (i.e. soit
représenté par un type unique en interne).



Ça c'est l'exemple qu'on trouve partout du Cray - les 32 bits devenant
64 ou 128 ? - et qui me paraît sain et dans la lettre et l'esprit de la
norme. J'imaginerais d'ailleurs sans qu'il existe beaucoup de machins
genre DSP ou micro-controleurs avec une taille unique de registres et
d'entiers natifs.

Du moment qu'il sait caster correctement (unsigned char) 0xFFFFab en
0xab (car la norme dit UCHAR_MAX = 0xFF)



La norme dit plus exactement que UCHAR_MAX doit être fourni par
limits.h et ne peut être inférieur à 0xFF.

et des choses de ce genre, ça
suffit.



J'ai du mal à vous suivre. Que fait ce 0xFFFFab, sur 24 bits ? Et si
comme vous l'indiquez CHAR_BIT vaut 32, et bien entendu sizeof(char)
vaut 1, pourquoi le compilateur aurait-il besoin de caster ?

Seules les limites min, max et umax sont imposées (dans <limits.h>),
après la taille que le compilo gère en interne c'est sa tambouille.
Tout ce qu'on lui demande c'est de savoir caster correctement et gérer
les opérations arithmétiques en concordance avec les limites imposées.

En particulier rien n'interdit qu'un short soit codé sur 128 bits et
un long sur 32 bits. Je vous l'accorde, niveau optim c'est pas
terrible, mais ça respecte la norme.



On parle au départ d'un sizeof. Donc là on aurait sizeof(short) = 128 /
CHAR_BIT et sizeof(long) = 32 / CHAR_BIT. Et là je suis convaincu qu'on
va tomber en contradiction avec au moins un point dans 6.2.6 avec
lecture de 6.3.1.1 et 6.2.5.8.

Du coup, les concepteurs ont fait rimer limits.h avec la taille
utilisée en interne pour la représentation pour plus de simplicité et
de bon sens, mais à mon avis rien n'est imposée par la norme à ce
niveau.

Je me fourvoie peut-être, mais c'est ce que je comprends de la norme.



--
Pierre Maurette
Avatar
espie
In article <4a650ec7$0$421$,
candide wrote:
Bonjour,




J'ai lu ici même que : sizeof (short) <= sizeof (int) et de même que
sizeof (int) < sizeof (long).



Qui a ecrit ca ?

J'ai beau lire et relire la Norme, je ne vois pas où cela est garanti.



Ca ne l'est pas: sizeof(int) <= sizeof(long)
On a tous deja rencontre des archi ou sizeof(int) = sizeof(long).
Par exemple, sur amiga, il y avait deux modeles: un avec short=int bits et
long2 bits, et un avec short bits et int=long2 bits.
Assez classique pour l'epoque au demeurant.

Quelqu'un peut-il préciser ? Merci



Aujourd'hui, tu rencontreras assez souvent short=int2 bits et longd bits,
mais ca ne parait pas deraisonnable d'avoir aussi short2 bits,
int=longd bits.
Avatar
espie
In article ,
Pierre Maurette wrote:
On parle au départ d'un sizeof. Donc là on aurait sizeof(short) = 128 /
CHAR_BIT et sizeof(long) = 32 / CHAR_BIT. Et là je suis convaincu qu'on
va tomber en contradiction avec au moins un point dans 6.2.6 avec
lecture de 6.3.1.1 et 6.2.5.8.



C'est ce que je pensais aussi, mais apres relecture de la norme, elle fait
tres attention de distinguer padding et representation, typiquement,
6.2.6.2.6.

Une lecture un peu rapide ne me montre pas de contradiction evidente, meme
si je ne pense pas qu'aucune implementation ne viole sizeof(int)<=sizeof(long).
Avatar
candide
Pierre Maurette a écrit :


Il me semble que c'était explicite dans la version précédente de la
norme C,



La Norme C90 disait

6.1.2.5
(...)
In the list of signed integer types above, the range of values of each type is a
subrange of the values of the next type in the list.

Maintenant, quel lien peut-on faire entre range et sizeof dans la Norme
précédente, je ne sais pas si le texte est assez clair pour décider.





à moins que ce ne soit dans celle de C++. Dans la C99 que j'ai
sous les yeux, si on veut prouver, on doit pouvoir passer par 6.3.1.1
(définition de /integer conversion rank/), en particulier:
<CIT>
- The rank of a signed integer type shall be greater than the rank of
any signed integer type with less precision.
- The rank of long long int shall be greater than the rank of long int,
which shall be greater than the rank of int, which shall be greater than
the rank of short int, which shall be greater than the rank of signed char.
</CIT>
Ensuite on fait la relation entre le /rank/ et le /range/ en 6.2.5.8,
puis on regarde la représentation des types en 6.2.6 et la définition de
l'opérateur sizeof.





Oui, j'ai bien vu cela mais je ne vois pas en quoi cela contraint par exemple à
avoir :

sizeof(short) <= sizeof(int)

range(type) et sizeof(type) étant des choses différentes s'il y a du padding par
exemple.


J'ai du mal à trouver sur Usenet des infos _explicites_ sur cette question
néanmoins j'ai trouvé ceci qui va dans le même sens :

http://groups.google.fr/group/comp.unix.programmer/msg/dac7c5f9ff1a1510?hl=fr

(avait été posté aussi sur comp.std.c)
Avatar
candide
candide a écrit :

sizeof (int) < sizeof (long).



Lire : sizeof (int) <= sizeof (long)
Avatar
Pierre Maurette
Marc Espie, le 21/07/2009 a écrit :
In article ,
Pierre Maurette wrote:
On parle au départ d'un sizeof. Donc là on aurait sizeof(short) = 128 /
CHAR_BIT et sizeof(long) = 32 / CHAR_BIT. Et là je suis convaincu qu'on
va tomber en contradiction avec au moins un point dans 6.2.6 avec
lecture de 6.3.1.1 et 6.2.5.8.



C'est ce que je pensais aussi, mais apres relecture de la norme, elle fait
tres attention de distinguer padding et representation, typiquement,
6.2.6.2.6.

Une lecture un peu rapide ne me montre pas de contradiction evidente, meme
si je ne pense pas qu'aucune implementation ne viole
sizeof(int)<=sizeof(long).



Je regarde de belles images de montagne et de vélocipédistes à la télé,
je n'ai pas trop envie de regarder cette ?!!?!? de norme, et en plus
j'ai vraiment un problème avec les shall should would /and so on/.
Je considère la norme C est un document industriel technique, elle ne
décrit pas une construction mathématiquement pure, je n'ai pas vraiment
envie de la prendre en défaut, il me semble qu'on y passe facilement
beaucoup de temps. En tournant sur une demi-dourzaine de questions
toujours les mêmes.

Pragmatiquement, je crois que l'édifice s'écroule si les types "plain
C" en C89/90, C99 et C++ ne suivent pas les mêmes règles. Dont:
1 <= sizeof(char) <= /* ... */ <= sizeof(long long) avec les
contraintes supplémentaires de limits.h

Si on veut vraiment fouiner la C99, il me semble qu'il y a beaucoup de
choses à déduire dans 6.2.6, dont la lecture approfondie en anglais
n'est pas une activité estivale à ma portée. Par exemple je crois bien
que 6.2.6.1.4 élimine les implémentations "crocolion" avec des paddings
délirants, puisque le schéma de padding est homogène quand la taille -
le sizeof - varie.


--
Pierre Maurette
Avatar
espie
In article ,
Pierre Maurette wrote:
Je regarde de belles images de montagne et de vélocipédistes à la télé,
je n'ai pas trop envie de regarder cette ?!!?!? de norme, et en plus
j'ai vraiment un problème avec les shall should would /and so on/.
Je considère la norme C est un document industriel technique, elle ne
décrit pas une construction mathématiquement pure, je n'ai pas vraiment
envie de la prendre en défaut, il me semble qu'on y passe facilement
beaucoup de temps. En tournant sur une demi-dourzaine de questions
toujours les mêmes.



Dans mon experience, tous les trucs de la norme sont soigneusement peses.
Si un truc n'y est pas, c'est qu'il y a une implementation dans la nature
qui est differente, ou que les membres du comite ont deliberement laisse
le point ouvert.

Pragmatiquement, je crois que l'édifice s'écroule si les types "plain
C" en C89/90, C99 et C++ ne suivent pas les mêmes règles. Dont:
1 <= sizeof(char) <= /* ... */ <= sizeof(long long) avec les
contraintes supplémentaires de limits.h



Et pourtant, des choses ont change entre C89 et C99, et C++98 n'est pas
directement compatible avec C99. Et tout ne s'est pas ecroule.


En gros, t'as la flemme tu preferes regarder le tour de france, et tu dis
que tout ceci est du pinaillage (tu as raison). Mais bon, soit tu pinailles,
soit tu ne pinailles pas, mais tu ne peux pas tout evacuer sous la moquette
comme ca. ;-)
Avatar
Manuel Pégourié-Gonnard
Pierre Maurette scripsit:

Pragmatiquement, je crois que l'édifice s'écroule si les types "plain
C" en C89/90, C99 et C++ ne suivent pas les mêmes règles. Dont:
1 <= sizeof(char) <= /* ... */ <= sizeof(long long) avec les
contraintes supplémentaires de limits.h



Tiens, jusqu'ici je croyais que sizeof(char) == 1 par définition ?
J'avais fumé ?

--
Manuel Pégourié-Gonnard Institut de mathématiques de Jussieu
http://weblog.elzevir.fr/ http://people.math.jussieu.fr/~mpg/
1 2 3 4