The following code was compiled with VC++ Nov 2012 CTP on Windows 7 x64.
#include <fstream>
using namespace std;
int main()
{
ofstream fout("log.txt", ios::app|ios::trunc);
if (!fout)
{
cout << "An error occurred!" << endl; // Always go here! Why?
}
}
The cppreference.com website doesn't say that ios::app
cannot be combined with ios::trunc
.
What are the exact semantics of ios::app
and ios::trunc
?
The filebuf
constructor to which these flags are passed† has behaviours based on those flags defined in Table 132 in C++11:
+-----------------------------------+-------------------+
| ios_base flag combination | stdio equivalent |
| binary in out trunc app | |
+-----------------------------------+-------------------+
| + | "w" |
| + + | "a" |
| + | "a" |
| + + | "w" |
| + | "r" |
| + + | "r+" |
| + + + | "w+" |
| + + + | "a+" |
| + + | "a+" |
+-----------------------------------+-------------------+
| + + | "wb" |
| + + + | "ab" |
| + + | "ab" |
| + + + | "wb" |
| + + | "rb" |
| + + + | "r+b" |
| + + + + | "w+b" |
| + + + + | "a+b" |
| + + + | "a+b" |
+-----------------------------------+-------------------+
As you can see, your flag combination is not found in that table.
[C++11: 27.9.1.4/2]:
[..] If mode
is not some combination of flags shown in the table then the open fails.
Those are the semantics.
† [C++11: 27.9.1.7/2]
& [C++11: 27.9.1.11/2]
show us that the mode is passed from the stream object to the buffer object.
- app (=append): set the stream's position indicator to the end of the stream before each output operation
- trunc (=truncate) any current content is discarded, assuming a length of zero on opening.
As you can see, it doesn't make sense to put both together.