Quel type pour soustraire 2 size_t?

Quel type en C doit être utilisé pour représenter la différence entre les tailles de deux objects?

Comme size_t n’est pas signé, quelque chose comme

 size_t diff = sizeof (small_struct) - sizeof (big_struct); 

évidemment ne serait pas correct et il me semble qu’il n’y a pas de véritable équivalent signé.

ptrdiff_t semble tentant, mais

  1. comme son nom l’indique, il permet de soustraire des pointeurs.
  2. J’ai lu par exemple que les plates-formes segmentées telles que DOS ont une taille maximale d’object de 64 Ko, ce qui est représentable par 16 bits. Les pointeurs éloignés se composent toutefois d’une valeur de segment de 16 bits et d’une valeur de décalage de 16 bits. Cela ne ferait-il pas de ptrdiff_t sur ptrdiff_t sur une telle plate-forme 32 bits? Si tel est le cas, la différence de taille entre deux objects ne nécessite que 16 bits, mais l’utilisation de ptrdiff_t vous donnera une variable d’une largeur de 32 bits, la rendant ainsi sous-optimale.

Alors, quel est le type portable approprié pour travailler avec une telle valeur?

Edit: Je connais ssize_t, mais c’est

  1. ne fait pas partie de la norme C.
  2. effectivement pas destiné à une telle utilisation, mais pour renvoyer une taille ou une valeur d’erreur (négative).

Il n’existe pas de type de données standard sûr à 100% pour ce que vous essayez de faire. Pour preuve, imaginez si size_t est vraiment juste uint64_t , ce qui est tout à fait possible. Ensuite, aucun type de données C standard n’a la garantie de disposer d’une plage positive qui correspond à uint64_t et gère également les valeurs négatives.

La réponse brute à votre question est donc “pas de type de données” (en supposant le ssortingct respect de la norme C, ce que vous semblez souhaiter).

Cependant, votre cas d’utilisation n’est pas clair et il est possible que vous puissiez tirer parti de l’arithmétique modulaire pour gérer les valeurs “négatives”. Par exemple, le code suivant a pour résultat que d2 est d2 à 4 raison de l’arithmétique modulaire, ce qui permet au code d’agir comme si la size_t était signée:

 #include  #include  int main() { size_t d1 = sizeof(int32_t) - sizeof(int64_t); size_t d2 = sizeof(int64_t) + d1; // Add difference (even if d1 is "negative"*) printf("d1: %zu\n", d1); printf("d2: %zu\n", d2); return 0; // * By "negative" I mean that d1 would be negative if size_t were signed } 

L’arithmétique modulaire peut ne pas vous suffire dans votre cas, mais peut l’être pour d’autres.

Lorsque je suis vraiment préoccupé par des problèmes de débordement comme celui-ci (en particulier lorsque je travaille en arithmétique modulaire où les valeurs “négatives” se situent ailleurs que ~0 ), je le divise en deux cas:

 if (a > b) { size_t diff = a - b; } else { size_t diff = b - a; // code here subtracts diff rather than adds it, etc. } 

Il n’y a pas de type entier C signé qui puisse contenir toutes les valeurs d’une valeur size_t .

Vous pouvez faire ceci:

 size_t diff = std::abs(static_cast  (sizeof (small_struct) - sizeof (big_struct)));