Why do I see THROW in a C library? Why do I see THROW in a C library? c c

Why do I see THROW in a C library?


This header is likely shared between the C and C++ compiler for that vendor. Did you look what __THROW is defined as?

I suspect something akin to:

#ifdef __cplusplus    #define __THROW throw()#else    #define __THROW#endif

Or for actual specifications:

#ifdef __cplusplus    #define __THROW(x) throw(x)#else    #define __THROW(x)#endif

As you can see, in a C build, it expands to nothing. In C++, it does what you expect. This allows vendors to reuse the same file.


Just to nitpick, this isn't entirely true: "(which is only a C library - nothing to do with C++)"

The C++ standard library includes the ability to use the C standard library. The actual header is <cxxx> where xxx is the C header name. That is, to include the C header <stdlib.h> in C++, you do <cstdlib>. So it does have to do with C++. :)

This is why you see the code you do. Duplicating the header for two different languages would be a nightmare for maintenance and cleanliness.


You can do

cpp -include stdlib.h -dM /dev/null  |grep '#define __THROW '

to learn what it actually expands to.

On my system, I get:

#define __THROW __attribute__ ((__nothrow__ __LEAF))

The nothrow and leaf attributes are described at https://gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/Common-Function-Attributes.html#Common-Function-Attributesas follows:

leaf

leaf Calls to external functions with this attribute must return to the current compilation unit only by return or by exception handling. In particular, a leaf function is not allowed to invoke callback functions passed to it from the current compilation unit, directly call functions exported by the unit, or longjmp into the unit. Leaf functions might still call functions from other compilation units and thus they are not necessarily leaf in the sense that they contain no function calls at all. The attribute is intended for library functions to improve dataflow analysis. The compiler takes the hint that any data not escaping the current compilation unit cannot be used or modified by the leaf function. For example, the sin function is a leaf function, but qsort is not.

Note that leaf functions might indirectly run a signal handler defined in the current compilation unit that uses static variables. Similarly, when lazy symbol resolution is in effect, leaf functions might invoke indirect functions whose resolver function or implementation function is defined in the current compilation unit and uses static variables. There is no standard-compliant way to write such a signal handler, resolver function, or implementation function, and the best that you can do is to remove the leaf attribute or mark all such static variables volatile. Lastly, for ELF-based systems that support symbol interposition, care should be taken that functions defined in the current compilation unit do not unexpectedly interpose other symbols based on the defined standards mode and defined feature test macros; otherwise an inadvertent callback would be added.

The attribute has no effect on functions defined within the current compilation unit. This is to allow easy merging of multiple compilation units into one, for example, by using the link-time optimization. For this reason the attribute is not allowed on types to annotate indirect calls.

nothrow

nothrow The nothrow attribute is used to inform the compiler that a function cannot throw an exception. For example, most functions in the standard C library can be guaranteed not to throw an exception with the notable exceptions of qsort and bsearch that take function pointer arguments.

What __attribute__((nothrow)) means in C is answered at gcc - what is attribute nothrow used for? . Basically, it's for cooperation with C++ code, and you can use it if the function won't ever call back to exception-throwing C++ code.


To answer your other question concerning "This function is a possible cancellation point and therefore not marked with __THROW": This deals with multi-threading. You can "cancel" a thread, but it won't actually "cancel" until it reaches a cancellation point. Some more info: http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_cancel.3.html