ftell an einer position in der Vergangenheit 2GB
Auf einem 32-bit-system, was bedeutet ftell
zurück, wenn die aktuelle position Anzeige der Datei im Binärmodus geöffnet ist Vergangenheit die 2GB Punkt? In der C99 standard, ist diese Undefiniertes Verhalten seit ftell
muss wieder ein long int
(maximalen Wert 2**31-1
)?
- Wenn, wie Sie gesagt haben, es ist Undefiniertes Verhalten, gibt es keine Möglichkeit, (sicher oder zuverlässig) sagen. Könnte es einfach nur wieder die richtige Zahl, -1, 0, a random number, könnte es segfault, oder es könnte senden einer swat-team.
Du musst angemeldet sein, um einen Kommentar abzugeben.
auf long int
long int
soll MINDESTENS 32-bit, aber C99-standard NICHT eine Begrenzung auf 32-bit.C99-standard bietet Komfort Typen wie
int16_t
&int32_t
etc, die Karte zu korrigieren bit-Größen für eine Zielplattform.auf ftell/fseek
ftell()
undfseek()
sind auf 32 bit beschränkt (einschließlich Vorzeichenbit) auf die überwiegende Mehrheit der 32-bit-Architektur-Systeme. Also, wenn es Unterstützung für große Dateien, die Sie ausführen in das 2GB Problem.POSIX.1-2001-und SysV-Funktionen für
fseek
undftell
sindfseeko
undftello
weil Sie off_t als parameter für den offset.müssen Sie festlegen, kompilieren mit
-D_FILE_OFFSET_BITS=64
oder definieren Sie es irgendwo, bevor stdio.h, um sicherzustellen, dassoff_t
ist 64-bit.Lesen Sie über diese auf die cert.org secure coding guide.
Auf Verwirrung zu ftell und die Größe der long-int -
C99 sagt
long int
muss mindestens 32-bit es NICHT sagen, dass es nicht größer seinversuchen Sie die folgenden für die x86_64-Architektur:
Beachten Sie, dass
1L
ist nur einlong
dies erzeugt eine Datei, die 17 GB und die sticks"\nhello world\n"
zu Ende. Die Sie überprüfen können, ist es von trivial mittail -n1 test.out
oder explizit mit:Beachten Sie, dass dd verwendet in der Regel block-Größe von
(1 << 9)
so34 - 9 = 25
wird dump aus'\nhello world\n'
x86_64
archs. Insbesondere lange auf 64-bit-windows ist immer noch 32-bit-Größe.Zumindest auf einem 32-bit OS
ftell()
wird es überlauf oder Fehler oder führen Sie einfach in ein Undefiniertes Verhalten.Dies zu umgehen, können Sie gerne verwenden
off_t ftello(FILE *stream);
und#define _FILE_OFFSET_BITS 64
.Wörtlich aus
man ftello
:Update:
Laut IEEE Std 1003.1, 2013 Edition
ftell()
ist zurück-1
- und set -errno
zuEOVERFLOW
in solchen Fällen:ftell
gibt immer0
in solchen Fällen, aber ein überlauf scheint zu implizieren, die Möglichkeit, eine negative Rendite. Sind überläufe garantiert "wrap-around" in der , C99, standard, oder wird diese bestimmt durch die Umsetzung?0
sehe ich keine reson für diese. Vermutlich wird die ganze Sache laufen in der UB? Vermeiden Sie es einfach! Jedoch UB könnte führen zu nichts ... es könnte auch zurückkehren, 42 dann! 😉If an exceptional condition occurs during the evaluation of an expression (that is, if the result is not mathematically defined or not in the range of representable values for its type), the behavior is undefined.
ftell
selbst bewirkt den überlauf -- oder ist der Wert, den es gibt für diese Fälle nicht spezifiziert?On failure, the ftell function returns −1L and stores an implementation-defined positive value in errno.
Leider, ich glaube, es lässt die definition von "Ausfall" bis zur Umsetzung; so vielleicht der Rückgabewert ist UB für 2 GB?Gibt es keine 64b bewusst Methode im C99-standard. Was OS/Umgebung sind verwenden Sie? Bei windows gibt es
_ftelli64
.Auf anderen Plattformen, schau http://forums.codeguru.com/showthread.php?277234-Cannot-use-fopen()-öffnen-Datei-größer-als-4-GB -
_ftelli64()
und nichtftell()
.long
"mindestens 32 bit lang" bedeutet, dass es exakt 32 bit lang sind. Es ist kein Bedarf zu haben, dass es 64 bit. Auch ich do Stimme dir zu, dass es seltsam ruhig für ein 64bit OS zu habenlong
weniger dann 64 bit lange ... 😉 Allerdings ist für den Abschluss von meiner argumentation die Antwort richtig ist, ist es nicht?