I have a C++11 program that uses std::fprintf
to write to stderr
as a log and debug info. I know fprintf
can fail and return a negative value, but I can't found if the operation is atomic (if fails, has no effect) or it can write some part of the text and then fails (or any other side effect).
The function that uses fprintf
looks like this:
void writeToConsole (std::string const &message)
{
std::fprintf(stderr, "%s\n", message.c_str());
}
I am developing using Clang and GCC on Linux (for now), but my question is more about the standard, so...
If std::fprintf
fails, is still possible that some characters had been written to stderr
? Is this behaviour a C/C++ standard or is implementation-defined?
Even more, if std::fprintf
fails, should I abort the program or can continue execution silently without side effects (other than impossibility of write to stderr
)?
Keep in mind that the printf
family of functions (almost always) eventually turns into a write(2)
function call (or other such low-level, OS/implementation-provided equivalent). This function can be partially successful. If at least one byte is written, the function succeeds (if no error from the underlying destination can be detected - for example, interruption by a signal handler) and it will return the number of bytes actually written:
The number of bytes written may be less than count if, for example, there is insufficient space on the underlying physical medium, or the RLIMIT_FSIZE resource limit is encountered (see setrlimit(2)), or the call was interrupted by a signal handler after having written less than count bytes. [...]
For information about partial writes, see write(2)
, for example at http://man7.org/linux/man-pages/man2/write.2.html. Values for errno
or other effects of a partial write may be dependent on the output medium (or what the file descriptor represents - memory mapped file, regular file, etc.), as well as the specific reason for failure. For example, ENOMEM,
EIO,
EDQUOT
are all possibilities.
Also see the linked man page for additional information about atomicity with regard to multiple threads.
Your other question:
Even more, if std::printf fails, should I abort the program or can continue execution silently without side effects (other than impossibility of write to stderr)?
This really depends on your program.
For fprintf
the C++11 standard falls back to C99 since it is part of the C standard library and the C99 draft standard says the following:
The fprintf function returns the number of characters transmitted, or a negative value if an output or encoding error occurred.
but does not actually specify whether an error means no character were transmitted or not, so that will end up dependent on the implementation.
For POSIX compliant systems, which in this case should cover Linux, the reference for fprintf says:
Upon successful completion, the fprintf() and printf() functions shall return the number of bytes transmitted.
[...]
If an output error was encountered, these functions shall return a negative value.
There are several errors listed that could lead to partial output such as:
[ENOMEM]
Insufficient storage space is available.
Whether an error indicates that you should exit your application depends on your application, do you have an alternate logging mechanism other than stderr
? Does your application have legal requirements that mandate everything is logged or are the logs purely informational, etc...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With