简体   繁体   中英

Override C code to throw a C++ exception?

I have a C library (callable from C and C++ code) which handles invalid input by simply exiting. It looks like this

#ifdef __cplusplus
extern "C" {
#endif

void exitWithError(const char* func) {
    printf("woopsie in %s", func);
    exit(1);
}

void myfunc(int i) {
    if (i < 0)
        exitWithError(__func__);
}

#ifdef __cplusplus
}
#endif

This library is compiled in "C mode", even when linked with C++ code. Ie using

g++ -x c <abovelibrary.c>

I'm using this library in C++ code, and desire it to throw an exception, in lieu of exiting. Eg

void exitWithError(const char* func) {
    throw std::invalid_argument( func );
}

Is it possible to use pre-processor directives to redefine exitWithError in C++, so that it throws an exception to the external calling C++ code, but is still compatible by the internal calling C code?

Can this further be done without modifying the original C library (although this is not a strict requirement)?

For context, I'm using the C++ Catch2 library to unit test the underlying C library, and wish to test that invalid user inputs are being correctly handled (using Catch2's REQUIRE_THROWS macro). I'm using C++14 if that matters, and the C library conforms to C99.

As per this question , we can declare exitWithError as a weak symbol from within the C library

#pragma weak exitWithError
void exitWithError(const char* func) {
    printf("woopsie in %s", func);
    exit(1);
}

and redefine it in C++, throwing an exception.

extern "C" void exitWithError(const char* func) {
    throw std::invalid_argument(func);
}

As pointed out in the comments, one must be absolutely sure they understand the internal state of the C library when exitWithError is invoked, and hence that it's safe to continue after catching the exception.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM