Le but est de faire pid_t
ou tout autre type de ce genre, indépendant de la plate-forme, de sorte qu'il fonctionne correctement quelle que soit la manière dont il est mis en œuvre. Cette pratique est utilisée pour tout type qui doit être indépendant de la plate-forme, tel que :
-
pid_t
: Doit être assez grand pour stocker un PID sur le système pour lequel vous codez. Correspond à int
pour autant que je sache, bien que je ne sois pas le plus familier avec la bibliothèque GNU C.
-
size_t
: Un unsigned
variable capable de stocker le résultat de la sizeof
opérateur. Généralement de taille égale à la taille des mots du système pour lequel vous codez.
-
int16_t
( intX_t
) : Doit être exactement de 16 bits, quelle que soit la plateforme, et ne sera pas défini sur les plateformes qui n'utilisent pas 2 n -(typiquement 8 ou 16 bits) ou, beaucoup plus rarement, fournissent un moyen d'accéder à exactement 16 bits d'un type plus grand (par exemple, les "octets" du PDP-10, qui peuvent être n'importe quel nombre de bits contigus d'un mot de 36 bits, et donc être exactement de 16 bits), et ne supportent donc pas les types entiers de complément à deux de 16 bits (comme un système de 36 bits). Correspond généralement à short
sur les ordinateurs modernes, bien que cela puisse être un int
sur les plus anciens.
-
int_least32_t
( int_leastX_t
) : Doit être la plus petite taille possible pouvant stocker au moins 32 bits, par exemple 36 bits sur un système à 36 ou 72 bits. Correspond généralement à int
sur les ordinateurs modernes, bien que cela puisse être un long
sur les plus anciens.
-
int_fastX_t
: Doit être le type le plus rapide possible qui peut stocker au moins X bits. En général, c'est la taille du mot du système si (X <= word_size)
(ou parfois char
para int_fast8_t
), ou agit comme int_leastX_t
si (X > word_size)
)
-
intmax_t
: Doit être la largeur maximale des entiers supportée par le système. Généralement, ce sera au moins 64 bits sur les systèmes modernes, bien que certains systèmes puissent supporter des types étendus plus larges que long long
(et si oui, intmax_t
doit être le plus grand de ces types).
- Et plus encore...
Mécaniquement, il permet à l'installateur du compilateur de typedef
le type approprié à l'identifiant (qu'il s'agisse d'un type standard ou d'un type interne maladroitement nommé) en coulisse, que ce soit en créant les fichiers d'en-tête appropriés, en le codant dans l'exécutable du compilateur ou par une autre méthode. Par exemple, sur un système 32 bits, Microsoft Visual Studio implémentera la fonction intX_t
et des types similaires comme suit (note : commentaires ajoutés par moi) :
// Signed ints of exactly X bits.
typedef signed char int8_t;
typedef short int16_t;
typedef int int32_t;
// Unsigned ints of exactly X bits.
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
// Signed ints of at least X bits.
typedef signed char int_least8_t;
typedef short int_least16_t;
typedef int int_least32_t;
// Unsigned ints of at least X bits.
typedef unsigned char uint_least8_t;
typedef unsigned short uint_least16_t;
typedef unsigned int uint_least32_t;
// Speed-optimised signed ints of at least X bits.
// Note that int_fast16_t and int_fast32_t are both 32 bits, as a 32-bit processor will generally operate on a full word faster than a half-word.
typedef char int_fast8_t;
typedef int int_fast16_t;
typedef int int_fast32_t;
// Speed-optimised unsigned ints of at least X bits.
typedef unsigned char uint_fast8_t;
typedef unsigned int uint_fast16_t;
typedef unsigned int uint_fast32_t;
typedef _Longlong int64_t;
typedef _ULonglong uint64_t;
typedef _Longlong int_least64_t;
typedef _ULonglong uint_least64_t;
typedef _Longlong int_fast64_t;
typedef _ULonglong uint_fast64_t;
Sur un système 64 bits, cependant, ils ne seront pas nécessairement implémentés de la même manière, et je peux garantir qu'ils ne seront pas implémentés de la même manière sur un système 16 bits archaïque, en supposant que vous puissiez trouver une version de MSVS compatible avec celui-ci.
Globalement, elle permet au code de fonctionner correctement, quelles que soient les spécificités de votre mise en œuvre, et de répondre aux mêmes exigences sur n'importe quel système compatible avec les normes (par ex. pid_t
peut être garanti comme étant suffisamment grand pour contenir tout PID valide sur le système en question, quel que soit le système pour lequel vous codez). Il vous évite également d'avoir à connaître les détails et de devoir chercher les noms internes que vous ne connaissez peut-être pas. En bref, cela permet de s'assurer que votre code fonctionne de la même manière, peu importe si pid_t
(ou tout autre typedef similaire) est implémentée comme un int
, a short
, a long
, a long long
ou même un __Did_you_really_just_dare_me_to_eat_my_left_shoe__
pour que vous n'ayez pas à le faire.
En outre, il sert de documentation, vous permettant de savoir en un coup d'œil à quoi sert une variable donnée. Prenons l'exemple suivant :
int a, b;
....
if (a > b) {
// Nothing wrong here, right? They're both ints.
}
Maintenant, essayons encore une fois :
size_t a;
pid_t b;
...
if (a > b) {
// Why are we comparing sizes to PIDs? We probably messed up somewhere.
}
S'il est utilisé comme tel, il peut vous aider à localiser des segments de code potentiellement problématiques avant que quelque chose ne casse, et peut rendre le dépannage beaucoup plus facile qu'il ne le serait autrement.