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)
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
.
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.
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.