

*******************
Language extensions
*******************

The Calypsi C compiler supports several C language extensions that can
be convenient. However, consider their portability implications.

.. index:: overloaded functions, language extensions; overloaded functions

Overloaded functions
====================

The overloaded functions support provides overloading of functions in
C similar to C++. Overloading in C is introduced using the
``overloadable`` attribute. For example, you might provide several
overloaded versions of a ``sine`` function that invokes the appropriate
standard function computing the sine of a value with ``float``,
``double``, or ``long double`` precision:

.. code-block:: C

   #include <math.h>

   float __attribute__((overloadable)) sine(float x) { return sinf(x); }
   double __attribute__((overloadable)) sine(double x) { return sin(x); }
   long double __attribute__((overloadable)) sine(long double x) { return sinl(x); }

The compiler calls the most suitable function based on argument types.
Overloaded functions are name mangled as C uses a single global
namespace.

.. index:: statement expression, language extensions; statement expression

Statement expressions
=====================

This GCC extension allows a statement to appear where an expression is
expected. Use it to allow loops, switches, and local variables within
an expression.

A compound statement is a sequence of statements enclosed by
braces. In the example below, parentheses around the braces create
a statement expression:

.. code-block:: C

   ({ int y = foo (); int z;
      if (y > 0) z = y;
      else z = - y;
      z; })

The last statement in a statement expression is an expression followed
by a semicolon. In this case, the variable ``z`` is used as the
result of the entire statement expression.

Safe macros
^^^^^^^^^^^

Statement expressions can also implement safe macros that evaluate
their parameters only once.

Recall the well known ``max`` macro:

.. code-block:: C

   #define max(a,b)  ((a) > (b) ? (a) : (b))

When used, this expands the largest value twice, which may be
undesirable if it has side effects or represents an expensive
computation.

With a statement expression this can be expressed as:

.. code-block:: C

   #define maxint(a,b) \
       ({int _a = (a), _b = (b); _a > _b ? _a : _b; })

While this solves the double-evaluation issue, it introduces other
subtle problems. First, you need to specify the type (see also
``__auto_type`` extension below), and it may cause variable shadowing.

In most cases, inline functions offer a better alternative to statement
expressions. Inline functions avoid subtle variable shadowing problems,
result in more readable code, and generate equally efficient code when
inlined. The minor caveat is that inline functions may not be inlined,
while statement expressions are always expanded in place.


.. index:: auto_type, language extensions; auto_type

Auto type
=========

The auto type extension allows specifying a type that is automatically
selected, using the ``__auto_type`` keyword. The declaration must
declare only one variable, whose declarator must be an identifier.
The declaration must be initialized, and the variable type is
determined by the initializer type.

Using __auto_type, the "max" macro in the previous section can be
written to select the type automatically:

.. code-block:: C

   #define max(a,b) \
       ({__auto_type _a = (a); \
         __auto_type _b = (b); \
         _a > _b ? _a : _b; })

.. index:: typeof, language extensions; typeof

Typeof
======

Refer to the type of an expression using ``__typeof``. The syntax
resembles ``sizeof``, but semantically, it acts like a typename defined
with ``typedef``.

Similar to ``sizeof``, there are two ways to write the argument to
``__typeof``: with an expression or with a type. For example, with an
expression:

.. code-block:: C

   __typeof (x)

This creates a type identical to the identifier ``x`` in the current
context.

You can also use a typename as an argument:

.. code-block:: C

   __typeof (int *)

In this case, the type is simply a pointer to ``int``.

Typeof can also be used to implement the "max" macro:

.. code-block:: C

   #define max(a,b) \
       ({__typeof (a) _a = (a); \
         __typeof (b) _b = (b); \
         _a > _b ? _a : _b; })

Generics
========

C11 style ``_Generic`` is now supported. This allows expressions to
expand to different outcomes based on a controlling expression. For
example:

.. code-block:: C

   extern void stringFunc(char*);
   extern void otherStringFunc(char*);
   extern void string4Func(char[4]);

   #define F(X) _Generic(&(X),        \
     default: otherStringFunc,        \
     char**: stringFunc,              \
     char(*)[4]: string4Func,         \
     char const**: stringFunc,        \
     char const(*)[4]: string4Func    \
     )(X)

   void foo(char *p) {
     F(p);
     F("foo");
     F("longer string");
   }


The macro ``F`` calls different functions based on its input. For
example, a string literal ``"foo"`` (3 characters plus null terminator)
is treated as a ``char`` array of 4 bytes, leading to a call to
``string4Func()``. The ``p`` parameter, an ordinary ``char*``,
results in a call to ``stringFunc()``. Finally, ``"longer string"`` is
treated as a ``char`` array with a length other than four, matching the
``default:`` alternative and resulting in a call to
``otherStringFunc()``.
