Is it "legal" for a C ++ runtime to call terminate () when C ++ code is used inside some program other than C ++?

In some cases - especially when an exception escapes the destructor during the unwinding of the stack - C ++ runtime terminate() runtime calls that should do something reasonable posthumous and then exit the program. When the question “why so harsh” is the answer, usually “there is nothing more reasonable to do in such situations with errors”. This sounds reasonable if the whole program is in C ++.

Now, what if C ++ code is in the library and the program using the library is not in C ++? This happens quite often - for example, I may have my own C ++ COM component consumed by the .NET program. As soon as terminate() is called inside the component code, the .NET program suddenly terminates abnormally. The author of the program will first think: "I do not care about C ++, why the hell is this library coming out of my program?"

How to handle the last scenario when developing libraries in C ++? Is it reasonable that terminate() terminates the program unexpectedly? Is there a better way to deal with such situations?

+7
c ++
source share
4 answers

Why does a C ++ call at runtime call terminate() ? He does not do this at random or because of circumstances that cannot be determined and / or avoided when the code is written. This is because your code is executing what is defined to call the terminate() call, for example, throwing an exception from the destructor while unwinding strings.

The C ++ standard has a list of all situations that are defined to call the terminate() call. If you do not want terminate() called, do not do any of this in your code. The same goes for unexpected() , abort() , etc.

I don’t think this is really different from the fact that you need to avoid undefined behavior or to avoid code spelling altogether. You should also avoid behavior that is defined, but undesirable.

Perhaps you have a specific example where it is difficult to avoid calling terminate() , but an exception from the destructor when unpacking the stack excludes it. Just don't throw exceptions from destructors, never. This means that you are designing your destructors so that if they do something that might fail, the destructor catches an exception and your code continues in a certain state.

There are several situations where your system will powerlessly crack your lap process because of what your C ++ code is doing (though not by calling terminate() ). For example, if the system is excessive memory, and VMM cannot run promises malloc/new , then your process may be killed. But this is a system function and probably applies equally to another language that your C ++ calls. I don't think you can (or should) do anything if your caller knows that your library can allocate memory. In this case, this is not your code error, the process has died, it is a certain response of the operating system to conditions with low memory.

+10
source share

I think the more fundamental problem is not what ends, but the design of the library. A library can only be developed for use with C ++, in which case exceptions can be caught and handled appropriately in the application.

If the library is intended to be used in combination with applications other than C ++, it needs to be provided with an interface that does not exclude exceptions from the library, for example, an interface that does catch (...).

+6
source share

Suppose you have a function in C ++ called cppfunc and you call it from another langugage (like C or .NET). I suggest you create a wrapper function, say exportedfunc , for example:

 int exportedfunc (resultype * outresult, paramtype1 param1, / * ... * /)
 {
     try {
        * outresult = cppfunc (param1, param2, / * ... * /);
        return 0;  // indicate success
     } catch (...) {// may want to have other handlers
        / * possibly set other error status info * /
        return -1;  // indicate failure
     }
 }   

Basically, you need to make sure that exceptions do not cross the boundaries of the language ... so you need to wrap your C ++ functions with a function that catches all exceptions and reports a status code or does something acceptable, except for calling std :: terminate,

+1
source share

The default completion handler will call abort . If you do not want this behavior, define your own completion handler and set it using set_terminate .

0
source share

All Articles