Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ equivalent of perror?

As far as I'm aware, my two options for handling stream errors are perror and stream exceptions. Both options are undesirable. Here's why:

perror

  • std::strerror returns an implementation-defined message. This message is not always useful on all systems

  • std::strerror is not thread-safe

  • The pointer returned by std::strerror can be invalidated

  • The C library is technically "deprecated" in C++. There's almost always a C++-ish equivalent. There's no reason why I should have to rely on POSIX and C when there's a potential C++ equivalent

stream exceptions

  • Exceptions are not appropriate for every program

  • While std::strerror can sometimes provide a useful error message, stream exceptions never provide a useful error message. With f.exceptions(f.failbit), for both failure to open a file or failure to extract, the exception thrown is std::ios_base::failure and the what() is "basic_ios::clear".

system_error

Replacing std::ios_base::failure with std::system_error produces exactly the same results. If we take a look at N2769: Detailed Reporting for Input/Output Library Errors (Revision 2), we can see why:

When throwing ios_base::failure exceptions, implementations are encouraged to provide values of ec that identify the specific reason for the failure. [Note - Errors arising from the operating system would typically be reported as system_category errors with an error value of the error number reported by the operating system. Errors arising from within the stream library would typically be reported as error_code(ioerrc::stream, iostream_category) -- end note].

The above wording provides only normative encouragement for implementers to do the right thing, and thus relies on market forces and the good intensions of implementers to produce results useful to users. Anything stronger (such as changing "are encouraged to" to "shall") would require much additional specification and is beyond the scope of what the LWG can realistically tackle for C++0x.

The alternative is to potentially rely on a bulky third party library (I'm looking at you Boost) or to hand-roll it (which you never want to do unless you know what you're doing.) I'm looking for the C++ standard library way to do this. Is there any?

like image 611
user5371056 Avatar asked Sep 24 '15 08:09

user5371056


People also ask

What is a perror in C?

The perror() function displays the description of the error that corresponds to the error code stored in the system variable errno . errno is a system variable that holds the error code referring to the error condition. A call to a library function produces this error condition.

What does perror return in C?

The C library function void perror(const char *str) prints a descriptive error message to stderr. First the string str is printed, followed by a colon then a space.

What is perror?

Description. The perror() function prints an error message to stderr . If string is not NULL and does not point to a null character, the string pointed to by string is printed to the standard error stream, followed by a colon and a space.

Why is perror printing success?

Essentially the string representation of "errno" a global variable is printed out along with your arguments. If you have no errors (errono = 0). This is causing your program to print "SUCCESS".


1 Answers

I do not agree with you on

perror et alii are member of C standard library and as such technically deprecated(*).

Well even on cplusplus.com if not an official documentation source, I see for errno:

C++11 expands the basic set of values required to be defined in this header... In C++, errno is always declared as a macro, but in C it may also be implemented as an int object with external linkage.

My understanding of those sentences is that errno is still considered in C++11!

I can even see later

Libraries that support multi-threading shall implement errno in a per-thread basis: With each thread having its own local errno. This is a requirement in libraries compliant with C11 and C++11 standards.

it means that even if strerror() is not thread-safe, errno is in any C++11 compliant implementation.

It is now up to you to use std::strerror in a synchronized function (for example protected with a mutex) to build a std::string if you like. But anyway, even if every documentation on strerror states that it uses a static buffer that could be overwritten (that's why Posix 1 defines strerror_r), I could not find any warning on perror not beeing thread safe.

(*) My opinion on that is that whenever OO and templates can give a nicer interface (iostream vs stdio.h or string vs. string.h), elements of the C library are replaced by others in C++ library. But when there is nothing to add (cerrno, cmath, csignal, etc.) the functions from C standard library are simply included in C++ one.

like image 181
Serge Ballesta Avatar answered Oct 03 '22 10:10

Serge Ballesta