I tried googling it but all results were about C++’s throw std::exception()
.
I was reading through libraries (was curious how stuff like printf
, malloc
and FILE
were implemented) and came across the definition for the malloc
function:
extern void *malloc (size_t __size) __THROW __attribute_malloc__
__attribute_alloc_size__ ((1)) __wur;
When using the IDE (Visual Studio Code) to trace back to definitions for each thing, __THROW
led to this:
# if !defined __cplusplus && __GNUC_PREREQ (3, 3)
// stuff that doesn't happen
# else
# if defined __cplusplus && __GNUC_PREREQ (2,8)
# define __THROW throw ()
# define __THROWNL throw ()
# define __NTH(fct) __LEAF_ATTR fct throw ()
# define __NTHNL(fct) fct throw ()
// continuation to the if-else macro
This confused me, as, as far as i know, c doesn’t have exceptions and instead uses int error codes. Even more, why are there parentheses as in a function call?
What does it mean and what does it do in the presented case?
3
Answers
The C 2017 standard doesn’t define a
throw
keyword. The header file may be used by both C and C++ compilers and as @Barmar noted it doesn’t apply to C (in C++, btw,throw()
specifier means that the function doesn’t throw exceptions).There is no
throw
keyword in C. In C, the source textthrow
is an ordinary identifier.The macro
__THROW
you show is replaced by nothing (an empty sequence of preprocessor tokens) when compiling in C, because the compilers the code you show is targeted for define__cplusplus
only when compiling as C++, not when compiling as C. So, in C,!defined __cplusplus_
is true, and the// stuff that doesn't happen
happens. You do not show that code, but it likely contains#define __THROW
or equivalent, defining__THROW
to be replaced by the empty sequence.If you see other statements being used, where
__THROW
is defined to be replaced bythrow ()
, then you are compiling in C++ mode, not C.There is no
throw
keyword in C. That’s a C++ thing.As to why you find it in your code, the clue is right here in the preprocessor macros:
This code is written so it will compile with either a C or C++ compiler. The C++ bit that references
throw
and other C++isms will only be compiled if a C++ compiler is used, as such a compiler will define the__cplusplus
macro.When you compile it with a C compiler, only the bit marked
// stuff that doesn't happen
will be used, not the else block.