I have this idiomatic snippet for getting the length of a binary file:
fseek(my_file, 0, SEEK_END);
const size_t file_size = ftell(my_file);
…I know, to be pedantic fseek(file, 0, SEEK_END)
has undefined behavior for a binary stream [1] – but frankly on the platforms where this is a problem I also don't have fstat()
and anyway this is a topic for another question…
My question is: Should I check the return value of fseek()
in this case?
if (fseek(my_file, 0, SEEK_END)) {
return 1;
}
const size_t file_size = ftell(my_file);
I have never seen fseek()
been checked in a case like this, and I also wonder what kind of error fseek()
could possibly ever return here.
EDIT:
After reading Clifford's answer, I also think that the best way to deal with fseek()
and ftell()
return values while calculating the size of a file is to write a dedicated function. However Clifford's good suggestion could not deal with the size_t
data type (we need a size after all!), so I guess that the most practical approach in the end would be to use a pointer for storing the size of the file, and keep the return value of our dedicated function only for failures. Here is my contribution to Clifford's solution for a safe size calculator:
int fsize (FILE * const file, size_t * const size) {
long int ftell_retval;
if (fseek(file, 0, SEEK_END) || (ftell_retval = ftell(file)) < 0) {
/* Error */
*size = 0;
return 1;
}
*size = (size_t) ftell_retval;
return 0;
}
So that when we need to know the length of a file we could simply do:
size_t file_size;
if (fsize(my_file, &file_size)) {
fprintf(stderr, "Error calculating the length of the file\n");
return 1;
}