C ++ utilise le streamoff
type pour représenter un décalage dans un flux (de fichier) et est défini comme suit dans [stream.types]:
using streamoff = implementation-defined ;
Le type streamoff est synonyme de l'un des types intégraux de base signés de taille suffisante pour représenter la taille de fichier maximale possible pour le système d'exploitation. 287)
287) Typiquement longue et longue.
Cela a du sens, car il permet de rechercher dans des fichiers volumineux (par opposition à l'utilisation long
, qui ne peut avoir qu'une largeur de 32 bits).
[filebuf.virtuals] définit basic_filebuf
la fonction de rechercher dans un fichier comme suit:
pos_type seekoff(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out) override;
off_type
est équivalent à streamoff
, voir [iostreams.limits.pos]. Cependant, la norme explique ensuite les effets de la fonction. Je suis irrité par la toute dernière phrase, qui nécessite un appel à fseek
:
Effets :
width
notonsa_codecvt.encoding()
. Siis_open() == false
, ouoff != 0 && width <= 0
, l'opération de positionnement échoue. Sinon, siway != basic_ios::cur
ouoff != 0
, et si la dernière opération a été sortie, mettez à jour la séquence de sortie et écrivez toute séquence non décalée. Ensuite, recherchez la nouvelle position: siwidth > 0
, appelezfseek(file, width * off, whence)
, sinon appelezfseek(file, 0, whence)
.
fseek
accepte un long
paramètre. Si off_type
et streamoff
sont définis comme long long
(comme suggéré par la norme), cela pourrait conduire à une conversion vers le bas long
lors de l'appel fseek(file, width * off, whence)
(conduisant à des bogues potentiellement difficiles à diagnostiquer). Cela remet en question toute la justification de l'introduction du streamoff
type en premier lieu.
Est-ce intentionnel ou un défaut dans la norme?
seekoff
nécessairement à des utilisationsfseek
sous le capot. Le comportement (vraisemblablement familier?) Defseek
est plutôt utilisé pour expliquer ce quiseekoff
se passe.fseek
tant qu'elle fait quelque chose avec le même effet. Maisfseek
avec un décalage inférieurLONG_MIN
ou supérieur àLONG_MAX
n'a aucun effet, donc l'explication est au mieux incomplète, au moins pour les implémentations oùstreamoff
est plus large quelong
.Réponses:
Je pense que la conclusion que vous tirez de cela, qu'il existe une incompatibilité entre les flux C ++ et
fseek
qui conduira à des bogues d'exécution, est incorrecte. La situation semble être:Sur les systèmes où
long
est 64 bits,streamoff
est défini commelong
et laseekoff
fonction appellefseek
.Sur les systèmes où
long
est 32 bits mais le système d'exploitation prend en charge les décalages de fichiers 64 bits,streamoff
est défini commelong long
etseekoff
appelle une fonction appeléefseeko
oufseeko64
qui accepte un décalage 64 bits.Voici un extrait de la définition de
seekoff
sur mon système Linux:LFS signifie Large File Support .
Conclusion: Bien que la norme suggère une définition pour
streamoff
cela en conflit ostensiblement avec l'exigence d'seekoff
invocationfseek
, les concepteurs de bibliothèques comprennent qu'ils doivent appeler la variantefseek
qui accepte la gamme complète de décalages pris en charge par le système d'exploitation.la source
The situation seems to be:
- La situation est que la mise en œuvre n'a pas le droit de ne pas appelerfseek
àseekoff
. Il doit appelerfseek
, ce n'est pas le cas, la norme dit qu'il doit le faire. Je peux affirmer que cette implémentation n'est pas valide. Je pense que cela ne répond pas à la question. Och, trouvé llvm , il appellefseeko
._fseeki64
cette fonction; qui semble également violer ce que dit la norme.fseek
. Ailleurs, la norme décrit quelque chose comme «comme si en appelantfseek(...)
». Si cela tenait tant à appeler littéralementfseek
, cette déclaration serait différente. Sérieusement, que feriez-vous si vous implémentiez une bibliothèque C ++? Souhaitez-vous insister pour appelerfseek
avec les 32 bits inférieurs d'un décalage de fichier 64 bits, car un document vous le demande? Vos clients vous en remercieraient-ils?