Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
497 views
in Technique[技术] by (71.8m points)

c - ftell at a position past 2GB

On a 32-bit system, what does ftell return if the current position indicator of a file opened in binary mode is past the 2GB point? In the C99 standard, is this undefined behavior since ftell must return a long int (maximum value being 2**31-1)?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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 '


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...