

****************
Efficient coding
****************

The Calypsi C compiler tool chain is designed for coding in memory-constrained environments, typically
embedded systems. This chapter explores proper data type usage and considerations
for both smaller and larger targets.

Even if your current coding targets a specific system, the code may evolve
and migrate to different system sizes. This chapter discusses trade-offs
between such environments.

Data types
==========

Data type selection significantly impacts overall program size and
execution speed. Here are some rules of thumb:

* Generally, use the smallest possible types.

* Floating-point operations are typically inefficient, consuming space
  and often executing slowly.

* Use variables with the narrowest possible scope.

* Avoid taking a variable's address. If necessary, limit its use as
  much as possible. The compiler cannot allocate such variables in
  registers (registers have no addresses), which prevents the optimizer
  from fully understanding how function calls affect the variable.

.. index:: integer types

Integer types
-------------

While smallest types are recommended, for larger targets, ``int`` and
``unsigned int`` can be more efficient, often being the sweet spot.

The ``stdint.h`` header provides integer types useful for selecting
appropriate sizes, optimizing efficiency, and ensuring portability.

A type like ``uint_fast16_t`` defines an unsigned integer of at least
16 bits, optimized for speed. An 8-bit target will use a 16-bit type,
while a 32-bit target might choose a 32-bit type if its instruction set
handles 32-bit operations more efficiently than 16-bit operations.

.. index:: floating point types

Floating point types
--------------------

Floating-point operations are often implemented using assembly or C
library routines, which consume code space and incur execution overhead.

Alternatively, use fixed-point integers (Q notation). For instance,
a Q24.8 number has 24 integer bits and 8 fractional bits, allowing
manipulation with standard integer operations. This requires scaling
values, which is straightforward.

.. index:: conversions; implicit

Implicit conversions
--------------------

C's conversion rules aim to convert integers to ``int`` and ``float`` to
``double``. This can introduce extra code. If this is a concern, you
must understand these rules or examine the compiler's generated code.

.. note::

   While studying generated assembly code may seem daunting, a basic
   understanding of its mechanics can be highly beneficial. The compiler
   can generate a list file (``-l`` or ``--list-file``) showing C code
   intermixed with the resulting assembly.

.. index:: prototypes; function, function prototypes

Use prototypes
==============

Functions can be declared using two styles. Traditional C, which lacks
prototypes, is not recommended as it hinders compiler error detection.
Prototypes offer safer, more efficient code generation by avoiding
certain type promotion rules that introduce extra code. Traditional
style is supported only for compatibility with older code. In this
style, a declaration does not specify parameters:

.. code-block:: C

   /* Traditional style */
   int foo();   /* declaration */

   int foo(c, i)   /* definition */
     char c;
     int i;
   {
     return i - c;
   }

In this case, the function takes a ``char`` parameter, which is
promoted to ``int`` during the function call, introducing additional
code.

Using prototypes with Standard C you specify parameters in the
declaration:

.. code-block:: C

   /* Standard C prototype style */
   int foo(char c, int i);   /* declaration */

   int foo(char c, int i)   /* definition */
   {
     return i - c;
   }

In this case the ``char`` parameter is not promoted to ``int`` and
is passed as a ``char`` type.


Use tables
==========

Consider the trade-off between calculating a value and using a table
for knowledge or operation encoding. For example, a sine operation in
Q (fixed-point) notation can be approximated with a table lookup
instead of calculation, making it very fast and compact.
