Summary of C18 features in the C compiler
=========================================

The current compiler supports a significant subset of features from the
ISO C standard (ISO/IEC 9899:2018). This document summarises the available
facilities.

C18 features and examples
-------------------------

     Static assertions with expressions resolved at compilation time

           #include <assert.h>
           static_assert(sizeof(msg_t) < 16, "Messages don't fit");

     noreturn

           #include <stdnoreturn.h>
           void noreturn busyloop(int unused)
           {
               while (1) {}
               /* not reached */
               for (int i = 0; i < 1000; i++)
                   unused++;
           }

     Complex type initialisation macros

           #include <complex.h>
           float complex       a = CMPLXF(3.0f, 4.0f);
           double complex      b = CMPLX(3.0, 4.0);
           long double complex c = CMPLXL(3.0, 4.0);

     Floating point limit macros in <float.h>

           Read the header file for more details.

     Encode string literals directly from wide characters or UTF-8

           char32_t *f = U"Fred";    /* Encoded at 32b per character */
           char16_t *j = u"Jim";     /* Encoded at 16b per character */
           char     *s = u8"Sheila"; /* Encoded in UTF-8 */

     Generic type selection

           #define mycos(r) _Generic((r), long double: cosl, \
                                          float      : cosf, \
                                          default    : cos \
                                    )(r)
           result = mycos(1.414f); /* Picks cosf based on type float */

     alignof

           #include <stdalign.h>
           printf("Structure has %u byte alignment\n", alignof(struct bbox));

     alignas

           #include <stdalign.h>
           int foo(void)
           {
               alignas(4) char a, b;
               return (int)&b - (int)&a; /* Will be a multiple of 4 */
           }

     max_align_t in <stddef.h>

           Read the header file for more details.

     Anonymous structures and unions

           Nested intermediate unions and structures can now be left with
           no name, creating them anonymously, and allowing them to be
           referenced shorthand. This is most often useful with unions (as
           in C++) since a structure could just as easily have been written
           flattened.

           typedef struct
           {
               int a;
               union
               {
                   int   b;
                   float c;
               }; /* No name here makes it anonymous */
               struct
               {
                   int   x, y, z;
               }; /* Also possible, an anonymous struct */
               struct
               {
                   int d;
               } tail;
           } mixture;
           mixture m;
           m.a = 7;
           m.c = 1.414f;
           m.d = 57; /* Invalid, d's struct has a name, so m.tail.d = 57 */
           printf("Float as hex %08X\n", m.b);

           This feature can be temporarily enabled in C99 and earlier modes
           by wrapping the structure definition in an 'anon_unions' pragma.
           Contrary to the pragma name this will enable both anonymous unions
           and structs. The name is compatible with armcc.

     New functions in the library

           void *aligned_alloc(size_t alignment, size_t size); // In <stdlib.h>
           int at_quick_exit(void (*func)(void));              // In <stdlib.h>
           void quick_exit(int status);                        // In <stdlib.h>
           int timespec_get(struct timespec ts, int base);     // In <time.h>

C18 changes
-----------
     The fopen() function now has an exclusive access mode, 'x'.
     Duplicate type definitions are no longer faulted, provided they are
     equivalent.

C18 removals
------------
     The gets() function has been withdrawn from <stdio.h> in C18.

Implementation notes
--------------------
If you use the new C18 library functions aligned_alloc(), at_quick_exit(),
quick_exit(), or timespec_get() you will need to ensure SharedCLibrary 6.05
or later is loaded. Other C18 language features (and things implemented in
headers just as macros) need only ensure the C99 or earlier features - see the
separate document regarding C99 library versions.

ISO/IEC 9899:2018 clarifies the position of some aspects of the earlier
standard ISO/IEC 9899:2011 but doesn't add or remove language features. There
is no C11 mode available. The compiler defines __STDC_VERSION__ to be 201710L.

The normative bounds-checking (annex K) and analysability (annex L) parts of
the standard are not supported.
Currently atomics and threads are also not supported, this can be detected
by the __STDC_NO_ATOMICS__ and __STDC_NO_THREADS__ being predefined.

Functions marked "noreturn" will be checked for paths that could return,
resulting in a warning if a return is deemed possible. In addition, any
unreachable code found in noreturn functions will be eliminated.

The alignas specifier may only be applied to automatic variables at present
due to limitations imposed by other parts of the tool chain, for example when
producing an AIF image or relocatable module. This is subject to future change
but is permitted by the C standard as an implementation defined feature.
The maximum alignment possible using alignas for an automatic variable is
implicitly determined by the current procedure calling standard; APCS-R and
APCS-32 both use 4 byte stack alignment.

There is no library support for those functions in <uchar.h>.

Selecting the standard
----------------------
The compiler defaults to C18 (or "-ansi" mode) which is highly compatible
with C99.
To explicitly select C99 or C90 mode use the "-c99" or "-c90" command-line
switches respectively. In the event of multiple standard selections the
highest version specifier (of "-pcc", "-c90", "-c99" and "-ansi/c18") wins.
