I found this interesting code in /usr/include/stdio.h
on various Linux systems I have access to.
167 /* Standard streams. */
168 extern struct _IO_FILE *stdin; /* Standard input stream. */
169 extern struct _IO_FILE *stdout; /* Standard output stream. */
170 extern struct _IO_FILE *stderr; /* Standard error output stream. */
171 /* C89/C99 say they're macros. Make them happy. */
172 #define stdin stdin
173 #define stdout stdout
174 #define stderr stderr
Question: What's the point in defining a macro that does essentially nothing?
The C11 defines stdin
, stdout
and stderr
in 7.21.1p3:
The macros [defined in
<stdio.h>
] are[...]
stderr
stdin
stdout
which are expressions of type pointer to
FILE
that point to theFILE
objects associated, respectively, with the standard error, input, and output streams.[...]
Since the standard says these are macros, they must be macros. However the expressions must have some definition, and the standard allows them to also be used as variable names, but they don't have to be actual identifiers.
Linux userland tries to mostly conform to the POSIX standard in addition to conforming to the C11 standard. In POSIX, the requirement is that these symbols are external identifiers. Since C11 requires that they be macros and POSIX requires that they're external identifiers, this is achieved easiest by defining a macro by the exact same name as the corresponding identifier.
It is indeed debatable if the POSIX standard intends them to also be variables with external linkage, but it is of note that POSIX.1 2008 standard does state in its System Interfaces volume that
The only sections relating to conformance are the SYNOPSIS, DESCRIPTION, RETURN VALUE, and ERRORS sections.
And the SYNOPSIS section for these does say that:
SYNOPSIS
#include <stdio.h> extern FILE *stderr, *stdin, *stdout;