Next Previous Contents

## 5. Extensions

This cc65 version has some extensions to the ISO C standard.

- The compiler allows to insert assembler statements into the output file. The syntax is

  > `

  >             asm (<string literal>[, optional parameters]) ;

  > `

  or

  > `

  >             __asm__ (<string literal>[, optional parameters]) ;

  > `

  The first form is in the user namespace and is disabled if the `-A` switch is given. There is a whole section covering inline assembler statements, see there.
- There is a special calling convention named "fastcall". The syntax for a function declaration using fastcall is

  > `

  >             <return type> fastcall <function name> (<parameter list>)

  > `

  or

  > `

  >             <return type> __fastcall__ <function name> (<parameter list>)

  > `

  An example would be

  > `

  >             void __fastcall__ f (unsigned char c)

  > `

  The first form of the fastcall keyword is in the user namespace and can therefore be disabled with the `--standard` command line option. For functions declared as `fastcall`, the rightmost parameter is not pushed on the stack but left in the primary register when the function is called. This will reduce the cost when calling assembler functions significantly, especially when the function itself is rather small.
- There are two pseudo variables named `__AX__` and `__EAX__`. Both refer to the primary register that is used by the compiler to evaluate expressions or return function results. `__AX__` is of type `unsigned int` and `__EAX__` of type `long unsigned int` respectively. The pseudo variables may be used as lvalue and rvalue as every other variable. They are most useful together with short sequences of assembler code. For example, the macro

  > `

  >             #define hi(x)           \
  >                 (__AX__ = (x),      \
  >                  asm ("txa"),       \
  >                  asm ("ldx #$00"),  \
  >                  __AX__)

  > `

  will give the high byte of any unsigned value.
- Inside a function, the identifier `__func__` gives the name of the current function as a string. Outside of functions, `__func__` is undefined. Example:

  > `

  >             #define PRINT_DEBUG(s)  printf ("%s: %s\n", __func__, s);

  > `

  The macro will print the name of the current function plus a given string.
- cc65 allows the initialization of `void` variables. This may be used to create variable structures that are more compatible with interfaces written for assembler languages. Here is an example:

  > `

  >             void GCmd = {   (char)3, (unsigned)0x2000, (unsigned)0x3000 };

  > `

  This will be translated as follows:

  > `

  >             _GCmd:
  >                     .byte   3
  >                     .word   $2000
  >                     .word   $3000

  > `

  Since the variable is of type `void` you may not use it as is. However, taking the address of the variable results in a `void*` which may be passed to any function expecting a pointer. See the GEOS library document for examples on how to use this feature.
- cc65 implements flexible array struct members as defined in the C99 ISO standard. As an extension, these fields may be initialized. There are several exceptions, however (which is probably the reason why the standard does not define this feature, because it is highly unorthogonal). Flexible array members cannot be initialized ...
  - ... when defining an array of structs with flexible members.
  - ... if such a struct is a member field of another struct which is not the last field.
  - ... if the struct which contains a flexible array member is declared as `register`, and the size and compiler settings do allow the compiler actually to place the struct into the register bank in the zero page.
  Please note that -- as defined in the ISO C standard -- the `sizeof` operator returns the struct size with the flexible array member having size zero, even if it is initialized.

Next Previous Contents