web-dev-qa-db-fra.com

Utilisation de ssize_t vs int

Code

J'ai une fonction que je peux écrire ne des quatre manières possibles:

int do_or_die(int retval);
int do_or_die(ssize_t retval);
ssize_t do_or_die(int t retval);   
ssize_t do_or_die(ssize_t retval);   

Et puis il sera appelé avec les deux de ces façons pour les fonctions de bibliothèque:

written = do_or_die(write(...)); // POSIX write returns ssize_t
printed = do_or_die(printf(...)); // printf returns int

Des questions

  • Quel prototype dois-je utiliser?
  • Quels types dois-je donner à written et printed?

Je veux avoir le code le plus robuste et le plus standard, tout en ayant un seul do_or_die une fonction.

J'utilise C99 dans ce cas, mais si la réponse est différente pour C11, alors j'aimerais le savoir aussi, pour l'avenir.

29
hyde

Il n'y a aucune garantie dans les normes C ou POSIX que sizeof(int) >= sizeof(ssize_t), ni l'inverse. Généralement ssize_t est plus grand que int, mais l'option sûre et portable de C99 consiste à utiliser intmax_t à la place pour l'argument et la valeur de retour.

Les seules garanties que vous avez. la relation entre int et ssize_t sont:

  • int peut stocker des valeurs d'au moins la plage [-2 ^ 15 ... 2 ^ 15-1] par ISO C
  • ssize_t peut stocker des valeurs d'au moins la plage [-1 ... 2 ^ 15-1] par POSIX (voir _POSIX_SSIZE_MAX ).

(Fait intéressant, il n'y a même pas de garantie que ssize_t peut stocker les équivalents négatifs de sa plage positive. Ce n'est pas un size_t, mais un "type de taille" avec une valeur d'erreur.)

43
Fred Foo

Utilisez les types d'une manière:

  • vous ne mélangez pas les types signed et unsigned ensemble et
  • vous ne tronquez pas les valeurs des types plus grands tout en les stockant dans des types plus petits (débordement/sous-dépassement)

ssize_t Peut être un alias pour int, mais ce n'est pas du C standard et peut être spécifique à l'environnement.

Si votre programme s'exécute dans un environnement spécifique, vérifiez si sizeof(ssize_t) <= sizeof(int) et utilisez int. Sinon, utilisez un autre type Tsizeof(T) est supérieur ou égal à la fois sizeof(int) et sizeof(ssize_t).

5
LihO