Skip to content

C language conformance

The DCC C Compiler is a C compiler for CP/M 2.2 on the Z80. This page describes language support for that target, not for a hosted desktop system. Its base language is C89, with selected C99 and C11 features added where they fit CP/M and the Z80.

Read the tables additively: start with the C89 support, then add the supported C99 features, then add the supported C11 features.

Target model

These limits apply at every language level.

Feature DCC C Compiler behavior
char 8 bits, signed
short, int 16 bits
pointers 16 bits
long 32 bits
float 32 bits
_Bool 8 bits, normalized to 0 or 1
double, long double not distinct types; use float
long long not supported
hosted environment outside the CP/M 2.2 target model
processes, threads, asynchronous signals, locale databases outside the CP/M 2.2 target model; C89 signal/locale APIs provide documented CP/M stubs/defaults

Practical implications of the target model

These follow directly from the table above and are often the source of portability surprises when code is moved from a hosted desktop compiler.

Practical rule What it means
int is 16-bit Use long (and %ld) for values beyond +/-32767. Code that assumes host-sized int or 64-bit arithmetic is outside the target model.
float is the only floating type Unsuffixed floating constants are treated as float; there is no wider double fallback.
atof returns float C89 declares atof as returning double; DCC C Compiler has no distinct double, so stdlib.h declares float atof(const char *).
float precision is ~24 bits Integers above about +/-16,777,216 are not all exactly representable as float; converting large long values rounds to nearest representable single precision value.
% is integer-only Use fmodf for floating-point remainder; float % float is a compile error.

C89 support

Language feature Status
Basic scalar types: char, short, int, long, float, void Supported, with the target sizes above
Signed and unsigned integer types Supported
Pointers, arrays, pointer arithmetic Supported
struct, union, enum Supported
Integer bit-fields Supported, packed into 16-bit units
Function declarations and prototypes Supported
Old-style function declarations and definitions Supported
typedef Supported
Storage classes: auto, extern, register, static Supported; auto is a no-op and register is only a hint
Type qualifiers: const, volatile Accepted for source compatibility; no CP/M/Z80 memory-model semantics are provided
Expressions and usual arithmetic conversions Supported within the target type model
if, switch, loops, break, continue, goto, return Supported
sizeof Supported
Preprocessor macros and conditional inclusion Supported
__FILE__, __LINE__, __DATE__, __TIME__, __STDC__ Supported
String literals and adjacent string literal concatenation Supported
Global and automatic initializers Supported

Missing from C89

Language or environment feature Status
Distinct double and long double arithmetic Not supported
Full hosted C library behavior Outside the CP/M 2.2 target model
Locale-sensitive execution environment Fixed to the C locale; no external locale database
Standard signal environment APIs exist, but CP/M has no asynchronous delivery; see the header contracts
Wide-character library behavior Outside the CP/M 2.2 target model
Read-only storage for const objects Outside the CP/M 2.2 memory model
Strict volatile memory/device access semantics Outside the CP/M 2.2 memory model
Forced register allocation from register Not implemented

C99 additions

C99 feature Status
_Bool Supported as a real scalar type
stdbool.h aliases: bool, true, false Supported
// comments Supported
Declarations in for loop initializers Supported
Mixed declarations and statements in nested blocks Supported
Unnamed parameters in prototypes Supported
Array parameters adjusted to pointers Supported
C99 array parameter qualifiers: int a[const 5], int a[static 5], int a[volatile 5], int a[restrict 5], int a[const *] Accepted as syntax compatibility; array parameters still decay to pointers
Variable-length arrays (local) Supported when the only variable dimension is the outermost, with constant inner dimensions (a[n], a[n][3]). The array decays to a pointer to stack-allocated storage and is reclaimed at ordinary block-scope exit, including loop iterations, break, continue, return, and a goto that leaves the scope (forward or backward, across any number of nested VLA scopes)
Function-typed parameters adjusted to pointers Supported
restrict qualifier Accepted as source compatibility; no alias-analysis optimization semantics are provided
Variadic macros and __VA_ARGS__ Supported
Empty variadic macro arguments Supported
Designated initializers for struct and array members Supported
File-scope compound literals in constant initializers Supported
Address-taking block-scope compound literals Supported
inline keyword Accepted; plain external inline is emitted as an ordinary function
static inline simple helper functions Supported for a useful subset
Trailing comma in enum lists Accepted as syntax compatibility

Missing from C99

C99 feature Status
long long and 64-bit integer types Not supported
Variable-length arrays with a variable inner dimension (a[n][m]) Not supported; the runtime row stride is not modelled (variable outermost dimension is supported, above)
goto/case entry into VLA scopes Not supported; a jump that would bypass a VLA's allocation is rejected. Jumps that leave VLA scopes — break, continue, return, and forward or backward goto — are fully supported and reclaim the stack correctly
sizeof applied to a whole VLA Supported for DCC's VLA subset; produces the VLA's run-time byte size
_Complex and complex arithmetic Not supported
Full C99 compound literal value semantics Partly supported only
Flexible array member initialization Not supported
C99 external inline linkage rules Not implemented
Full C99 floating-point environment Outside the CP/M 2.2 target model
Full C99 hosted library Outside the CP/M 2.2 target model

For the practical VLA guide — supported forms, block-scope reclamation in loops and recursion, and worked examples — see Variable-length arrays.

C11 additions

C11 feature Status
Anonymous struct members Supported
Anonymous union members Supported
Initialization through anonymous aggregate members Supported
_Static_assert declarations Supported at file, block, and struct/union member scope; <assert.h> also defines static_assert

Missing from C11

C11 feature Status
_Generic Not supported
_Atomic Outside the CP/M 2.2 target model
_Thread_local Outside the CP/M 2.2 target model
C11 threads Outside the CP/M 2.2 target model
C11 atomics library Outside the CP/M 2.2 target model
C11 bounds-checking interfaces Outside the CP/M 2.2 target model
Hosted C11 library additions Outside the CP/M 2.2 target model

Extensions accepted for compatibility

Extension Status
__attribute__((...)) in common declaration positions Ignored

Extensions not supported

Extension Status
GNU range designators, such as [0 ... 3] Not supported
Empty structures Not supported
Statement expressions, such as ({ ... }) Not supported
__builtin_expect Not supported