IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Quelle est la difference entre les variables de type INT et SHORT ?


Sujet :

C

  1. #21
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 374
    Points : 23 631
    Points
    23 631
    Par défaut
    Hello,

    Citation Envoyé par sevyc64 Voir le message
    Désolé de ne pas avoir fait attention que l'on était dans la rubrique C. Ma réponse se voulait généraliste tous langages confondus.

    Par contre je surpris quand tu dis que le short comme le int a une taille de 4 octets. Dans ma mémoire, le short avait bien une taille de 2 octets quand au Int il avait une taille de 2 octets (à l'époque ou j'ai appris le C sur des processeurs 16bits) et 4 octets sur les plateformes 32bits.
    Il s'agit en fait de tailles minimum garanties : Le C t'assure que tu pourras représenter de manière sûre, avec chaque type, une plage de nombres définies. Le C est un langage conçu pour s'adapter à tous les types de plateforme possibles, en tout cas la plupart et certaines sont très exotiques.

    Il se trouve que les tailles spécifiées par la norme dans limits.h (voir C99 §5.2.4.2) correspondent correspondent effectivement aux formats les plus courants et qu'on retrouve également dans les autres langages, mêmes anciens, ce qui est preuve de bon sens. Mais il est tout-à-fait possible que les types exacts ne soient pas disponibles sur la plateforme pour laquelle tu compiles. C'est vrai pour la largeur des nombres mais aussi pour certaines subtilités arithmétiques comme la représentation en complément à 1 (qui nous avait occupés ici). Et dans ce cas, le programme compilé est bien obligé de travailler sur le plus proche format par excès.

    Si tu fixes la taille des nombres et donc, en particulier, leur comportement lors des débordements, il est possible que le C ne puisse absolument pas compiler sur certains produits. C'est pourquoi la norme définit en parallèle stdint.h qui, lui, établit la correspondance entre les types natifs et les formats d'entiers à nombre de bits fixe.

    Dans le premier cas, tu es assuré de pouvoir utiliser les types natifs dans tous tes programmes et qu'ils seront valides sur les plages considérées. Dans le second, tu es sûr que les entiers auront le format souhaité s'ils sont disponibles, mais rien ne te garantit qu'il le soient.

    C'est aussi pour cela que la norme définit un grand nombre de cas « indéfinis » ou « spécifiques à l'implémentation ». Ce n'est pas le signe d'un document mal finalisé mais, au contraire, d'une notion importante qu'il faut savoir utiliser partout où c'est judicieux et surtout pas ailleurs. Imposer un comportement par défaut sans justification valable ferme de facto à toutes les classes d'architectures qui ne suivent pas le courant principal, ou leur impose des contraintes coûteuses et inutiles. C'est souvent le cas en électronique numérique, et spécialement en VHDL : si on a besoin d'un signal valide pour certaines conditions mais dont la valeur n'a pas de sens lorsqu'elles ne sont pas réunies, forcer ce signal à une valeur par défaut comme on initialiserait une variable en programmation séquentielle peut s'avérer extrêmement gourmand en logique combinatoire. Tous ceux qui ont eu un jour à programmer un FPGA se sont retrouvés confrontés à ce problème en dépassant sa capacité et ont dû faire des compromis pour faire tenir le tout dedans.

    Les nombres à virgules flottantes, maintenant, sont un poil différents parce qu'ils sont « artificiels ». Il faut donc choisir un format et s'y tenir. La norme la plus répandue à ce sujet est IEEE 754 et c'est celle qui est utilisée par la norme C. Outre le fait que ces nombres soient définis « en dehors » de C89/C99, il est nécessaire de fixer leur largeur à cause de l'aspect « composite » de leur format et parce que la largeur de l'exposant dépend aussi de celle de la mantisse.

    Et je suis encore plus surpris quand tu dis que "Les normes C ne définissent pas de tailles exactes pour chaque type mais une taille minimale". Certes je n'ai pas la connaissance absolue, et certainement des lacunes mais pour moi, les types Byte, Short, Long, DLong (long long), Float (single) et Double ont des tailles précisément définies et fixes indépendamment de tous langages. …
    C'est une erreur.

    Déjà, en soi, « byte » ne signifie pas « octet », contrairement à une idée répandue, mais plutôt quelque chose comme « boîte à bits ». Ensuite « short », « long » « dlong », etc. ne sont justement pas définis au niveau global, mais uniquement par les normes respectives des différents langages à leur propre niveau, et sont nés à la fois de l'état de l'art à l'époque de leur apparition et de l'historique qui menait jusqu'à cette époque.

    Par exemple, « word » signifie « mot ». On parle de « mot » à partir du moment où on fait une composition lexicale insécable en elle-même mais formée de plusieurs atomes, qui correspondent aux caractères en théorie des langages. On a utilisé le terme « mot » dans des contextes assez différents notamment quand on travaillait au niveau du bit.

    Et en particulier, on a longtemps travaillé sur huit bits, au point qu'encore aujourd'hui, c'est l'unité d'adressage native des x86 qui travaillent pourtant directement sur 32, voire 64 bits aujourd'hui. Quand on programmait en assembleur sur ce genre de machine, on travaillait donc au niveau de l'octet sur toutes les opérations arithmétiques, donc le résultat avait le même format que les opérandes SAUF pour la multiplication dont la largeur du résultat est par nature le double de celui des opérandes (au maximum). Si on considère qu'à partir du moment où on travaillait sur un format composé de plus d'un octet, on avait forcément un mot et qu'avec ça, le bus de ces micro-processeur mesurait généralement 16 bits de large (parce qu'il est inconcevable d'éditer un micro-processeur généraliste avec un plan de mémoire de seulement 256 octets), alors la plupart des micro-processeurs des années 1980, comme le 6809 ou le Z80, étaient conçus autour d'une architecture 8 bits mais étaient en pratique des 8/16 bits puisqu'ils étaient faits pour pouvoir agréger deux accumulateurs 8 bits en un registre de 16 (A et B vers D sur 6809 et B-C, D-E, H-L… sur Z80) en plus d'être dotés de registres d'index nativement 16 bits (à commencer par le pointeur de programme), mais sur lesquels on ne pouvait souvent faire que des translations d'adresse, soit des additions ou soustractions.

    Tout ceci a ancré l'association « mot = 16 bits » dans l'esprit collectif par opposition à l'octet puis, lorsque les architectures plus étendues ont commencé à se développer, on a inventé les « double mots », etc. toujours par comparaison avec les formats les précédant immédiatement.

  2. #22
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    946
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 946
    Points : 1 351
    Points
    1 351
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    la plupart des micro-processeurs des années 1980, comme le 6809 ou le Z80, étaient conçus autour d'une architecture 8 bits mais étaient en pratique des 8/16 bits puisqu'ils étaient faits pour pouvoir agréger deux accumulateurs 8 bits en un registre de 16 (A et B vers D sur 6809 et B-C, D-E, H-L… sur Z80) en plus d'être dotés de registres d'index nativement 16 bits (à commencer par le pointeur de programme), mais sur lesquels on ne pouvait souvent faire que des translations d'adresse, soit des additions ou soustractions.
    Seule exception à ma connaissance: Le 6502 (Atari, Apple, Commodore), qui n'a qu'un seul registre 16 bits, le pointeur de programme, PC. C'était loin d'être une bête de course, mais on y arrivait quand même.

    A+

    Pfeuh

  3. #23
    Membre éclairé
    Inscrit en
    Juillet 2012
    Messages
    231
    Détails du profil
    Informations forums :
    Inscription : Juillet 2012
    Messages : 231
    Points : 870
    Points
    870
    Par défaut
    Je suis globalement d’accord avec ce que dit Obsidian.
    Deux remarques cependant :
    Citation Envoyé par Obsidian Voir le message
    Si tu fixes la taille des nombres et donc, en particulier, leur comportement lors des débordements
    Un integer overflow est un comportement non défini, donc fixer la taille des nombres ne peut pas fixer leur comportement en cas de débordements. Ça sera toujours un comportement non défini.

    Citation Envoyé par Obsidian Voir le message
    La norme la plus répandue à ce sujet est IEEE 754 et c'est celle qui est utilisée par la norme C.
    Il me semble que la norme C n’impose rien au niveau du support de la norme IEEE 754.
    En C89, rien n’est spécifié (liberté totale).
    En C99, une annexe définie le support de l’IEEE 754 (si un compilateur veut le supporter, il doit se conformer à l’annexe), mais ne l’impose pas. D’ailleurs, on peut vérifier si une implémentation supporte IEEE 754 via la constante __STDC_IEC_559__ (mais ça reste moyennement fiable car certaines implémentation supportent IEEE 754 sans coller totalement à l’annexe et ne peuvent donc pas définir cette constante).
    Je ne sais pas ce qu’il en est du C11.

  4. #24
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Citation Envoyé par grim7reaper Voir le message
    Un integer overflow est un comportement non défini, donc fixer la taille des nombres ne peut pas fixer leur comportement en cas de débordements. Ça sera toujours un comportement non défini.
    J'ai l'impression que tu fais un raisonnement circulaire là. Je ne vois pas ce qui empêcherait une plate-forme de définir précisément tous les cas d'integer overflow; un code spécifique à cette machine ne sera donc pas indéfini dessus. Il sera non-portable évidemment, mais aura sur cette plate-forme un comportement garanti.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #25
    Membre éclairé
    Inscrit en
    Juillet 2012
    Messages
    231
    Détails du profil
    Informations forums :
    Inscription : Juillet 2012
    Messages : 231
    Points : 870
    Points
    870
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    J'ai l'impression que tu fais un raisonnement circulaire là. Je ne vois pas ce qui empêcherait une plate-forme de définir précisément tous les cas d'integer overflow; un code spécifique à cette machine ne sera donc pas indéfini dessus. Il sera non-portable évidemment, mais aura sur cette plate-forme un comportement garanti.
    Je crois que là tu parles de comportement défini par l’implémentation (implementation-defined behavior) ou alors de comportements non spécifiés (unspecified behavior), du genre ordre d’évaluation des arguments d’une fonction.
    Un integer overflow c’est comportement non défini (undefined behavior).

    Cela dit, même avec ce que tu dis je ne vois pas le rapport entre le fait de définir la taille d’un type et la définition de son comportement en cas de dépassement. Même si une implémentation définit comment gérer les dépassements, je ne vois pas en quoi un dépassement sur une variable 8 bits devrait avoir un comportement différent d’un dépassement sur une variable 16 ou 32 bits.

    Édit : pour les nuances entre implementation-defined behavior, unspecified behavior et undefined behavior voir cette FAQ ou cette discussion.

  6. #26
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    En gros, une implémentation n'a pas le droit de définir un undefined behavior et si elle le fait, elle n'est plus conforme au standard?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #27
    Membre éclairé
    Inscrit en
    Juillet 2012
    Messages
    231
    Détails du profil
    Informations forums :
    Inscription : Juillet 2012
    Messages : 231
    Points : 870
    Points
    870
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    En gros, une implémentation n'a pas le droit de définir un undefined behavior et si elle le fait, elle n'est plus conforme au standard?
    Si elle a le droit :
    the implementor may augment the language by providing a definition of the officially undefined behavior
    Ou encore :
    Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message) […]
    Cela dit ça va être très spécifique à cette implémentation. C’est pire que pas portable (déjà qu’avec les unspecified behavior tu as des comportements différents entre gcc et clang dans le même environnement (OS/architecture))
    Du genre : la version X du compilateur Y sur l’OS Z de l’architecture 42 pourra assurer tel comportement, mais la version X+1 du compilo’ pourrait totalement changer cela.
    De plus, une implémentation pourrait tout autant tirer un comportement au hasard ou quoique ce soit d’autre selon le numéro de la ligne du code.
    Avec un undefined behavior TOUT peut arriver. Absolument tout. Donc oui, ça peut éventuellement être défini.

    Il faut aussi savoir que les undefined behavior permettent aux compilateurs d’effectuer toute une classe d’optimisations. Les développeurs de LLVM avait fait un trés bon article (en 3 parties) à ce sujet.

    Édit : j’ai retrouvé l’article en question, si ça en intéresse certains.

Discussions similaires

  1. Quelle est la compatibilité entre les framework ?
    Par le lynx dans le forum Framework .NET
    Réponses: 3
    Dernier message: 13/09/2006, 09h28
  2. Réponses: 5
    Dernier message: 24/05/2006, 22h14
  3. Réponses: 8
    Dernier message: 17/05/2006, 10h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo