on long int
long int
is supposed to be AT LEAST 32-bits, but C99 standard does NOT limit it to 32-bit.
C99 standard does provide convenience types like int16_t
& int32_t
etc that map to correct bit sizes for a target platform.
on ftell/fseek
ftell()
and fseek()
are limited to 32 bits (including sign bit) on the vast majority of 32-bit architecture systems. So when there is large file support you run into this 2GB issue.
POSIX.1-2001 and SysV functions for fseek
and ftell
are fseeko
and ftello
because they use off_t as the parameter for the offset.
you do need to define compile with -D_FILE_OFFSET_BITS=64
or define it somewhere before including stdio.h to ensure that off_t
is 64-bits.
Read about this at the cert.org secure coding guide.
On confusion about ftell and size of long int
C99 says long int
must be at least 32-bits it does NOT say that it cannot be bigger
try the following on x86_64 architecture:
#include <stdio.h>
int main(int argc, char *argv[]) {
FILE *fp;
fp = fopen( "test.out", "w");
if ( !fp )
return -1;
fseek(fp, (1L << 34), SEEK_SET);
fprintf(fp, "
hello world
");
fclose(fp);
return 0;
}
Notice that 1L
is just a long
, this will produce a file that's 17GB and sticks a "
hello world
"
to the end of it. Which you can verify is there by trivially using tail -n1 test.out
or explicitly using:
dd if=test.out skip=$((1 << 25))
Note that dd typically uses block size of (1 << 9)
so 34 - 9 = 25
will dump out '
hello world
'
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…