skip to Main Content

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


  1. 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).

    Login or Signup to reply.
  2. There is no throw keyword in C. In C, the source text throw 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 by throw (), then you are compiling in C++ mode, not C.

    Login or Signup to reply.
  3. 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:

    # 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 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search