Search code examples
clanguage-lawyerrestrict-qualifierpointer-aliasing

Why can a fpos_t * alias a FILE *?


In Modern C, Jens Gustedt states that:

With the exclusion of character types, only pointers of the same base type may alias.

But then I find this declaration of fgetpos() in Annex B of the C standard:

int fgetpos(FILE * restrict stream, fpos_t * restrict pos);

where the fpos_t type is defined as:

which is a complete object type other than an array type capable of recording all the information needed to specify uniquely every position within a file.

which begs the question:

Why can a fpos_t * alias a FILE *? Is it because fpos_t can be a typedef for FILE ? If not, what justifies the use of restrict here?


Solution

  • First, the restrict in a function declaration that is not a definition has no effect in C semantics. C 2018 6.7.6.3 15 says parameter qualifiers are ignored when determining function compatibility, and that means the function could be declared with restrict on its parameters but defined without restrict or vice-versa. So the use of restrict in the documentation describing the routine is merely advice to the reader.

    Normally, a FILE and fpos_t will not alias each other. (And note it is the object we are concerned about aliasing, not the pointer. The rules about aliasing in 6.5 7 are about what lvalue types may be used to access an object, not about pointers may be used [except of course when considering actually aliasing a pointer].) However, you could (in the sense it is possible, not advisable) have declared a union that contains both a FILE (if your C implementation defines it as a complete type) and a fpos_t, so you are passing in a properly prepared FILE object and are willing to have it sacrificed and replaced by an fpos_t in the same memory. You could also be doing this with dynamically allocated memory, since writing a new type (fpos_t) over an old type (FILE) is an allowed form of aliasing (when writing to dynamically allocated memory, whatever type you are using is the effective type, which is allowed for aliasing). So the restrict in the documentation for fgetpos is advising you not to do that.