C++ alternative to perror()
Solution 1
You could do something like:
std::cerr << strerror(errno) << std::endl;
That still ends up calling strerror
, so you're really just substituting one C function for another. OTOH, it does let you write via streams, instead of mixing C and C++ output, which is generally a good thing. At least AFAIK, C++ doesn't add anything to the library to act as a substitute for strerror
(other than generating an std::string
, I'm not sure what it would change from strerror
anyway).
Solution 2
You could use the boost::system_error::error_code
class.
#include <boost/system/system_error.hpp>
#include <cerrno>
#include <iostream>
void
PrintError(
const std::string& message,
int error
)
{
std::cerr << message << ": " <<
boost::system::error_code(
error,
boost::system::get_system_category()
).message()
<< std::endl;
}
int
main()
{
PrintError( "something went wrong!", EINVAL );
return 0;
}
it's a tad verbose, and somewhat overkill if you aren't already using the boost_system library.
Solution 3
With C++11, we have the <system_error> header, so you should be able to use:
std::error_code{errno, std::generic_category()}.message();
Example program:
#include <system_error>
#include <iostream>
int main() {
std::cout << std::error_code{errno, std::generic_category()}.message() << '\n';
}
This prints Success
.
See also:
- How to convert errno to exception using <system_error>
-
<system_error> categories and standard/system error codes
(regarding whether to usegeneric_category
orsystem_category
)
Sagar
I'm a software engineer, working as part of an Infrastructure & Tools Team. My main interests are in Python, C, and C++ development, and continuous integration methodologies (including infrastructure tools such as Jenkins). I also love refactoring old/legacy software.
Updated on June 06, 2022Comments
-
Sagar almost 2 years
I know we can use
perror()
in C to print errors. I was just wondering if there is a C++ alternative to this, or whether I have to include this (and therefore stdio.h) in my program. I am trying to avoid as many C functions as possible.
-
Tyler McHenry almost 14 yearsA C++ version of
strerror
which would return astd::string
would presumably also be thread-safe, which would be a nice improvement. -
Jerry Coffin almost 14 years@Tyler: Well, that's certainly possible, and would be a handy improvement. OTOH, getting thread safety out of anything that uses
errno
almost unavoidably uses thread local storage anyway (i.e., about the same as it takes to makestrerror
thread safe). -
Tyler McHenry almost 14 years@Jerry I'm not sure about other threading frameworks, but POSIX threads guarantee that
errno
is thread-local automatically. The problem withstrerror
is that it returns a pointer to a static buffer that is not thread-local. -
Jerry Coffin almost 14 years@Tyler: My point was that to make
errno
work, you need to have and use TLS anyway, and once you're using it, you might as well use it forstrerror
's buffer too. -
Simon almost 14 years@Tyler McHenry: Having an error-message-creation-function that creates a std::string would be very inappropriate. How would that function work if it would try to report "out of memory"? I would say that an error-function that takes a char* buffer with a given size would be the most appropriate. It's also "thread-safe".
-
Simon almost 14 yearsWouldn't that be pretty bad if you happen to do PrintError("We ran out of memory!", EINVAL); when you discover that you failed to do a memory-allocation?
-
Tyler McHenry almost 14 years@Simon And there exists such a thing (
perror_r
), although you do have a point about out-of-memory errors. -
Sagar almost 14 yearsCan't actually use the boost library. This has to be as 'plain' (for lack of a better term) as possible. Trying not to include any 3rd party stuff. Thanks though!
-
Sagar almost 14 yearsThanks all. Really helpful! The fact that I can stream it makes me like it more. I don't like mixing C & C++ if I can help it. The sterror issue (non-local static buffers) is something I'll have to check, although we should be using POSIX threads, so...