web-dev-qa-db-fra.com

Quelles sont les différences d'utilisation entre size_t et off_t?

Outre la taille des valeurs que chaque type peut contenir, quelles sont les principales différences dans usage entre size_t et off_t? Est-ce simplement une convention selon laquelle les types size_t sont utilisés pour les tailles absolues et les types off_t pour les décalages? Ou va-t-il plus profond que cela?

J'écris une classe wrapper pour permettre l'écriture de gros fichiers avec mmap et je veux savoir quels sont les meilleurs types à utiliser pour leurs arguments. Étant donné que je veux écrire dans des fichiers> 4 Go, je suis tenté d'utiliser size_t pour tout, mais est-ce la meilleure pratique? (ou devrais-je utiliser des types off64_t pour certaines fonctions?)

Par exemple, ma fonction writeAt doit-elle être déclarée comme suit:

MMapWriter::writeAt(off64_t offset, const void* src, size_t size)

ou

MMapWriter::writeAt(size_t offset, const void* src, size_t size)
36
Lee Netherton

size_t est pour les objets, off_t est pour les fichiers.

mmap fusionne les deux concepts, presque par définition. Personnellement, je pense que j’utiliserais size_t, car quoi qu’il en soit, un fichier mappé est aussi un tableau dans la mémoire (virtuelle).

size_t est le standard C++, off_t est le Posix et off64_t est une extension GNU qui va aux fonctions fopen64, ftello64, etc. Je pense devrait toujours être du même type que off_t sur 64 bits GNU, mais ne pariez pas votre entreprise là-dessus sans vérifier.

Si cela est pertinent, off_t est signé alors que size_t est non signé. Mais la contrepartie signée de size_t est ptrdiff_t; ainsi, lorsque vous avez besoin d'un type signé, cela ne signifie pas automatiquement que vous devez utiliser off_t ou off64_t.

48
Steve Jessop

size_t fait partie des normes C++ (et C) et fait référence au type d'une expression sizeof. off_t est défini par le standard Posix et fait référence à la taille d'un fichier.

12
James Kanze

Bonne règle de base pour ce scénario. Utilisez la signature de fonction qui vous permet d'utiliser le moins possible de transtypage explicite, qu'il s'agisse de style c ou de style c ++. Si vous devez lancer des cast, le style c ++ est plus sûr car il est plus limité dans les types de cast qu'il peut faire.

L’avantage de cela est que si vous portez sur une plate-forme où les types ne correspondent pas (qu’il s’agisse d’un problème de signature, de taille ou d’endianisme, etc.), vous devriez détecter la plupart des bogues au moment de la compilation plutôt qu’au moment de l’exécution. Le casting est la méthode la plus puissante pour presser un objet de forme triangulaire dans un trou rond (plus ou moins vous dites au compilateur de rester silencieux, je sais ce que je fais).

Il peut être difficile d’essayer de résoudre les problèmes de casting au moment de l’exécution, car il peut être difficile à reproduire. Il est préférable de rechercher les problèmes au moment de la compilation plutôt qu'au moment de l'exécution. Le compilateur est votre ami.

0
ericcurtin