views:

102

answers:

2

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.

Thanks!

+5  A: 

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).

Jerry Coffin
A C++ version of `strerror` which would return a `std::string` would presumably also be thread-safe, which would be a nice improvement.
Tyler McHenry
@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 make `strerror` thread safe).
Jerry Coffin
@Jerry I'm not sure about other threading frameworks, but POSIX threads guarantee that `errno` is thread-local automatically. The problem with `strerror` is that it returns a pointer to a static buffer that is not thread-local.
Tyler McHenry
@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 for `strerror`'s buffer too.
Jerry Coffin
@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
@Simon And there exists such a thing (`perror_r`), although you do have a point about out-of-memory errors.
Tyler McHenry
Oh nice, I didn't know about perror_r. Thanks!
Simon
Sagar
+1  A: 

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.

Sam Miller
Wouldn'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?
Simon
Can'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