I have read on cppreference about Undefined behavior and understand the differences. What I didn't find though is what is implicit.
I would expect any behavior that is not explicitly defined to be unspecified behavior. But when I tried to find what t
means in fopen
's format string, there was nothing in the cppreference on it and nowhere does it state that it is implementation defined. What bugs me even more is that in notes it is explicitly stated about the filename
parameter.
On the other hand msdn defines among others the t
parameter so that would mean that any behavior not explicitly stated as undefined can be implementation defined? Or is the cppreference just missing a sentence and I'm only chasing ghosts?
I guess what the question boils down for me is, if there is nothing written about something, what is it, undefined or implementation defined behavior?
PS. The question is about general case so please don't tell me how to use fopen
"the right way" in the answers. The function was just an example.
The document to read about undefined / implementation-defined behaviour is the relevant standard for the language; i.e. for C for example the latest standard document is "ISO/IEC 9899:2011", also known as C11. As these are not freely available to public, we often use the last public working draft instead. For C11 the last public working draft is n1570, which is available at least at port70.net.
The C11 standard explicitly says the following of "undefined behaviour":
1 In this International Standard, ''shall'' is to be interpreted as a requirement on an implementation or on a program; conversely, ''shall not'' is to be interpreted as a prohibition.
2 If a shall or shall not requirement that appears outside of a constraint or runtime-constraint is violated, the behavior is undefined. Undefined behavior is otherwise indicated in this International Standard by the words undefined behavior or by the omission of any explicit definition of behavior. There is no difference in emphasis among these three; they all describe behavior that is undefined.
Thus any behaviour that is not explicitly defined in the standard, is, when it comes to the standard, is undefined, and every possible imaginable and unimaginable behaviour is equally acceptable.
Now, different implementations, like MSVC or GCC can give stronger guarantees for certain constructs - they can document that a certain behaviour can be expected in that implementation. However, if one wants to write portable C code, relying on such behaviour should be avoided.
As for fopen
, the C11 7.21.5.3p3) says that
The argument mode points to a string. If the string is one of the following, the file is open in the indicated mode. Otherwise, the behavior is undefined.
(emphasis mine)
And the list contains only r
, w
, wx
, a
, rb
, wb
, wbx
, ab
, r+
, w+
, w+x
, a+
, r+b
, rb+
, w+b
, wb+
, w+bx
, wb+x
, a+b
and ab+
; thus given a mode string with t
in it, the particular fopen
implementation is free to do absolutely anything it sees fit, including:
Yet the implementation can still be standard-conforming.