10

Some of the functions in stdio seem to have the stream as the last argument, for example:

char    *fgets(char *restrict, int, FILE *restrict);
int      fputs(const char *restrict, FILE *restrict);
size_t   fread(void *restrict, size_t, size_t, FILE *restrict);
size_t   fwrite(const void *restrict, size_t, size_t, FILE *restrict);

while some have it as the first argument:

int      fgetpos(FILE *restrict, fpos_t *restrict);
int      fseek(FILE *, long, int);

Why is this inconsistency? Were these functions added at different time in the evolvement of the standard library? In that case which were first, and why was the convention changed?

I realize that it's more or less needed for fprintf with friends to have the FILE* first (or at least early) due to the ellipsis (and for fclose and similar to have it first, and last).

skyking
  • 13,817
  • 1
  • 35
  • 57
  • Another example is fread, fwrite having arguments in order: size,count, while calloc, qsort, bsearch have those arguments in reverse. – 2501 Feb 24 '16 at 09:23
  • Well at least they are consistent in the sense that positional methods expect the first parameter as the file handle, while i/o methods with buffer expect the buffer first. – Selçuk Cihan Feb 24 '16 at 09:23
  • I very much doubt there is any rationale for this. I just checked the C rationale document and there is no mentioning of why parameters were ordered in one particular way or the other. Most standard library functions were originally ancient Unix functions. Things like common sense and scientific methods were never priorities for the C89 committee. They just merrily picked random, existing Unix functions and tossed them into the standard library, with no concerns or second thoughts. And so gems like `gets` and `strncpy` made it to the ISO standard. – Lundin Feb 24 '16 at 09:23
  • @Lundin I guess that the functions were already an etablished fact at the time of the C89 committee. I'd guess that one would dig deeper into the history to find the answer - or at least a reasonable theory. – skyking Feb 24 '16 at 09:30
  • 1
    `fgets(line,MAXLINE,fp)` prototype remains at least from K&R '78 edition: 'fgets` reads the next input `line` from file `fp`. Looks like naive literate programming... For `putchar(c,fp)`: put the character `c`on the file `fp, etc. – Jean-Baptiste Yunès Feb 24 '16 at 09:43
  • Side note: something is wrong with `fgetpos(FILE *restrict, fpos_t *restrict)`. – barak manos Feb 24 '16 at 10:40

1 Answers1

3

I am convinced that a clear and evident answer will not be found to this question, although, this question is not opinion-based, as a clear answer exists somewhere, even though it is unreachable.

However, I recognize the frustration about the problem: one cannot easily work, if, besides learning the function names and what they depend on, memorizing the parameter order for each function individually. Instead, it would be nice to have a consistent parameter order.

To achieve that, one can implement a consistent stdio library, which would use consistent order for the parameters and would wrap each stdio function into such a function. Example:

int      mystdio_fseek(long, int, FILE *);

This would return the result of

int      fseek(FILE *, long, int);

So, the mystdio_ might be a prefix to make sure that names are almost similar, but different and the parameter order would be consistent. This way, one would need to remember only the function names, what each function depends on and there will be no longer need to memorize the parameter order for each function individually. One could use these methods whenever there will be no need for micro optimization.

2501
  • 25,460
  • 4
  • 47
  • 87
Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175
  • 1
    @2501, I agree with you that mystdio_ would be a better prefix. – Lajos Arpad Feb 24 '16 at 10:39
  • 5
    The de facto standard for C function parameter order is generally (from left to right): destination, source (if applicable), other stuff. (For example, the parameter order of `memcpy`/`strcpy` is very canonical). If sticking to that, then `fseek` has the correct order, `fprintf(FILE*...` has the correct order, and the other functions have the incorrect order. – Lundin Feb 24 '16 at 10:44