jantristanmilan
jantristanmilan

Reputation: 4368

Why doesn't this purposely made invalid file positioning not bringing up any errors

So given a binary file containing 100 bytes. I'm pretty sure that the INVALID ones should cause and error, but why doesn't it? I'm confused the once in INVALID should bring up a semantic error right? Or am I misunderstanding something

/* VALID */  fseek(fp, sizeof(char) * 2, SEEK_SET);
/* VALID */  fseek(fp, -2 * sizeof(char), SEEK_END);
/* INVALID */fseek(fp, sizeof(char)* 2, SEEK_END);
/* INVALID */fseek(fp, -2 * sizeof(char), SEEK_SET);
/* INVALID */fseek(fp, 50, SEEK_CUR);
/* VALID */  fseek(fp, -50, SEEK_CUR);
/* INVALID */ fseek(fp, 51, SEEK_CUR);
/* INVALID */ fseek(fp, -51, SEEK_CUR);

Upvotes: 0

Views: 195

Answers (2)

librik
librik

Reputation: 3788

I don't know what sort of OS you are using (the fact that you say "binary file" suggests it's Windows), but on Unix-based systems the "seek" operation doesn't actually do anything immediately. So it is not really likely to crash.

Here are some excerpts from the description of the lseek function, the core Unix function that fseek and friends use, according to Advanced Programming in the Unix Environment by W. Richard Stevens:

Every open file has an associated "current file offset," normally a non-negative integer that measures the number of bytes from the beginning of the file. Read and write operations normally start from the current file offset and cause the offset to be incremented...

lseek only records the current file offset within the kernel -- it does not cause any I/O to take place. This offset is then used by the next read or write operation.

In short, the thing that fseek changes is likely to be just an integer variable inside a struct. Only when an actual I/O operation is requested does the Unix kernel access the file system. So "impossible" positions won't cause a crash.

Upvotes: 0

AnT stands with Russia
AnT stands with Russia

Reputation: 320531

What "semantic error" are you talking about?

Invalid file position will cause fseek to fail, which will be indicated by the return value of fseek. You have to receive that value and analyze it to determine whether the function succeeded or not. Your code above completely ignores the return value of fseek.

Keep in mind that the standard library does not require all platforms to support SEEK_END positioning. The platform might not know where exactly the end of file is (until you actually bump into it while reading the file). For example, some file systems might not store the exact file size in bytes, but rather store how many "blocks" or "sectors" that file occupies, which can only serve as approximate file size. For this reason the language specification states that SEEK_END positioning is not guaranteed to be meaningfully supported.

Also keep in mind that one some platforms it might be perfectly allowable to seek past the end of file opened for writing. The subsequent write operation will write data at the new position, while filling the "gap" with zeros.

Upvotes: 2

Related Questions