Reputation: 730
I would like to have a function along the lines of
/*In header*/
void foo(FILE *outpt=stdout);
/*In implementation*/
void foo(FILE *outpt)
{
if(outpt) fprintf(outpt, "Hello!");
}
But this code is (obviously) broken if NULL==stdout
. (Edit: Jonathan Leffler points out that this code is already broken, because C has no default arguments. My C++ is showing, but the idea remains.)
C specifies that stdin
, stdout
, and stderr
are implementation-defined FILE*
constants, but I can't find a reference indicating that these constants are not NULL
. Moreover, I can't find anything suggesting that NULL
might not be a valid open file!
In MSVS, fprintf(NULL, "Hello!")
calls abort()
, suggesting that NULL
is indeed an invalid FILE*
specification.
C++ seems to follow C in this regard. I'm ultimately a C++ programmer, but I'll take a C answer, because it then likely carries over to C++ for backwards compatibility. So: does a C or C++ specification (including C2x and C++20) guarantee that NULL
is an invalid FILE*
specification?
Upvotes: 3
Views: 621
Reputation: 224387
A NULL pointer, by definition, does not point to a valid object of any type. Whether or not the pointer type is FILE *
doesn't matter.
Section 6.3.2.3p3 of the C standard says the following regarding NULL pointers:
An integer constant expression with the value 0, or such an expression cast to type
void *
, is called a null pointer constant. If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function.
Attempting to dereference a NULL pointer invokes undefined behavior.
Section 6.5.3.3p4 of the C standard regarding the indirection operator states:
The unary
*
operator denotes indirection. If the operand points to a function, the result is a function designator; if it points to an object, the result is an lvalue designating the object.
If the operand has type ‘‘pointer totype’’, the result has type ‘‘type’’. If an invalid value has been assigned to the pointer, the behavior of the unary*
operator is undefined. 102)
And footnote 102 states:
... Among the invalid values for dereferencing a pointer by the unary
*
operator are a null pointer, an address inappropriately aligned for the type of object pointed to, and the address of an object after the end of its lifetime.
As these apply to NULL pointers in general, by extension it means that a FILE *
being set to NULL does not point to a valid FILE
object.
Upvotes: 0
Reputation: 40013
C11 7.21.1/3 describes the standard file handles thusly:
The macros 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.
They would not point to any such objects if their values were null.
Upvotes: 4
Reputation: 253
NULL is not a valid FILE*! Since stdout and stdin are treated like any other stream, the following applies…
https://man7.org/linux/man-pages/man3/fopen.3.html
RETURN VALUE Upon successful completion fopen(), fdopen() and freopen() return a FILE pointer. Otherwise, NULL is returned and errno is set to indicate the error.
Upvotes: 1