Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I see THROW in a C library?

When I do: less /usr/include/stdio.h (which is only a C library - nothing to do with C++)

I see __THROW after quite a few function declarations. Also, comments above a few functions say that 'This function is a possible cancellation point and therefore not marked with __THROW' What is all this for?

throw is meant to be for exception handling...but as far as I know, C doesn't provide any support for it.

Please explain.

like image 564
mynk Avatar asked Mar 21 '10 08:03

mynk


People also ask

What is__ throw in C?

__THROW is a macro which is setup by the headers to evaluate to blank in C and throw() in C++. That throw() does is specify the list of types of exceptions that the function may throw.

What are library files in C?

A library in C is a collection of header files, exposed for use by other programs. The library therefore consists of an interface expressed in a . h file (named the "header") and an implementation expressed in a . c file.


2 Answers

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.

like image 198
GManNickG Avatar answered Sep 21 '22 17:09

GManNickG


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-Attributes as 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.

like image 25
PSkocik Avatar answered Sep 21 '22 17:09

PSkocik