Extensions to the C language - DavidPH/GDCC GitHub Wiki

Attributes

Attributes allow you to specify some special properties for a function or object. GDCC supports both the GCC syntax:

__attribute__((comma separated list of attributes))

and more concise C++ syntax:

[[comma separated list of attributes]]

Both are usually placed immediately before the declaration of the target objects (more specifically, C++ rules are used for associating attributes).

Function attributes

call:

For functions, argument 1 is a string that specifies the call type, and can be any of the following:

  • StdCall - The normal C calling convention.

  • StkCall - The regular ACS calling convention. Does not pass the aut stack pointer and as such can't call StdCall functions.

  • ScriptI - A numbered ACS script.

  • ScriptS - A named ACS script.

  • SScriptI - A synchronous numbered ACS script. When an ACS script-type function calls a function with this call type, it will delay until the called function finishes execution.

  • SScriptS - A synchronous named ACS script. Same as SScriptI but with a named script.

  • LangASM - ???

  • LangC - alias to StdCall, this is the default calling convention.

  • LangACS - alias to LangACS.

  • Script - alias to ScriptI.

  • SScript - alias to SScriptI.

(The following are normally not useful in user code, and simply exist to declare native ACS functions, like p-code functions, ACS extension functions and line specials)

  • AsmFunc - instructions (p-codes as per the ZDoom definition) that behave similarly to functions. Requires an address attribute specifying the instruction number.
  • Native - ACS extension function (ACSF as per the ZDoom definition). Requires an address attribute specifying the function number.
  • Special - Line special. Requires an address attribute specifying the line special number.

script:

For functions (of ScriptI, ScriptS, SScriptI or SScriptS call type), argument 1 is a string that sets the script type or flags, and can be any of the following:

  • bluereturn
  • death
  • disconnect
  • enter
  • event
  • lightning
  • open
  • pickup
  • redreturn
  • respawn
  • return
  • unloading
  • whitereturn

Along with the flags:

  • clientside
  • net

All of these affect the script the same as in ACC. Multiple script attributes can be specified to add the flags on top of one script type.

optional_args:

For functions, argument 1 is a string that sets the amount of optional arguments (starting from the last one and counting until the first). For call types that do not support optional arguments (StdCall, StkCall and AsmFunc), optional arguments are replaced as if by static initialization (numeric types are zero and pointers are NULL).

alloc_Aut:

For functions (of ScriptI, ScriptS, SScriptI or SScriptS call type), argument 1 is an integer that sets the automatic storage stack size. Default is 4096 (can be modified with the --alloc-Aut command line parameter), and 0 effectively disables automatic storage for the function.

no_init_delay:

For functions (of ScriptI, ScriptS, SScriptI or SScriptS call type) with an ENTER or OPEN script type, disables the implicit 1-tic delay to wait for the static initialization scripts to execute. Static storage objects may not be initialized at the time of execution, however.

delay:

Marks a function as potentially delaying execution when called.

Object attributes

no_init:

Prevents a static object from being initialized as normal, so it's contents will be indeterminate at startup.

Common attributes

address:

For objects, argument 1 is an integer specifying the address of the object in its address space (and enforces static storage for the object). For ScriptI or SScriptI functions, arg 1 is an integer specifying the script number. For ScriptS or SScriptS functions, arg 1 is a string specifying the script name.

extern:

For objects and functions, argument 1 is a string that specifies the language linkage, and can be any of the following:

  • C - The default linkage.
  • ACS - Normally, GDCC does some name mangling that may prevent the function/object from being found outside of GDCC-compiled modules. This linkage disables that, and the identifier of the object will match it's linking name.
  • ASM - ???

Other attributes

return:

For ASM statements, indicates that the statement contains a return.

Expressions

__div

__div(<int>, <int>)

Returns a __div_t object with two members containing the quotient and remainder of the division.

Types

GDCC supports both Embedded C fixed point data types:

  • _Accum / __fixed - q16.16 fixed point number. Shorter aliases are defined in stdfix.h. Equivalent to the fixed point type in ZDACS. Can be prefixed with long for a q32.32 fixed point type, and can additionally be unsigned. Literals of this type are suffixed with the letter k/K (signed/unsigned respectively), or lk/LK for (signed/unsigned) long fixed, like so: 1.0k.

  • _Fract - A fractional number with no integral part. It's values range between -1.0 and 1.0 (not inclusive). Can be prefixed with long for a 64-bit fractional type, and can additionally be unsigned. Literals of this type are suffixed with the letter r/R for (signed/unsigned respectively), or lr/LR for (signed/unsigned) long fract.

It also introduces a couple other types of it's own:

  • __str_ent * / __str - Pointer to the ACS string table. Equivalent to the string type in ACS. String literals of this type must be prefixed with the letter s, like so: s"string". An uppercase S instead means explicitly of type char[] like in C.

  • __str_ent - Abstract type that simply exists to represent ACS string table pointers as pointers.

  • __div_t - return type of the __div expression, a struct type with two members (rem, for the remainder of the division, and quot, for the quotient of the division) corresponding to it's own type. As with the int type, it may be combined with long, signed and unsigned to alter the members' type.

Address spaces

To take full advantage of all kinds of storage in the ACS VM, GDCC has Embedded C address spaces. By default, everything is stored in a global array (which by default is global array 0, but can be changed with the --bc-zdacs-Sta-array command line parameter), and this is where all pointers point to by default. However address spaces allow storing objects in local ("script" scope) module ("map" scope), hub ("world" scope) and other global arrays and variables.

Intrinsic address space types

reg types span all variables (registers) of their type, as opposed to arrays. Usually only useful for interoperability with ACS or extreme performance requirements.

  • __loc_reg
  • __mod_reg
  • __hub_reg
  • __gbl_reg

ars types span all arrays of their type. Largely for internal use, not often useful for user code.

  • __mod_ars
  • __hub_ars
  • __gbl_ars
  • __str_ars - the result of __str plus an integer. A pointer to an ACS string plus an offset into that string. Comparatively useful.

arr types allocate only one array of their type. These require an __addrdef to actually reserve the relevant array, and then the defined address space can be used as usual.

  • __loc_arr - Useful for local function arrays.
  • __mod_arr - Very useful to avoid conflicts with other mods that would otherwise use the same space in the default address space.
  • __hub_arr
  • __gbl_arr

Syntax

To declare an object inside a particular address space, simply suffix the type in an object declaration as with const (while it can be a prefix instead, when declaring a pointer this would instead declare a pointer to the address space, but not stored in the address space, which may be confusing):

int <address space> test

in the case of a pointer (only changing it's storage, not the address space it points to), the address space name must go after the *.

int *<address space> test

To declare a pointer to a particular address space, include the address space name between the object type and the * in the declaration.

int <address space> *test

The __addrdef syntax is as follows:

__addrdef <arr type> <new address space name>

__addrdef is only required for the __*_arr types.

As an example. This defines a __mod_arr (module array) address space named test_mod, and a few variables inside it.

__addrdef __mod_arr test_mod;
int test_mod AnArray[10];
__str test_mod SomeString;
int test_mod* test_mod APointer;

/* This pointer points inside the test_mod address space, but is not itself stored in it.
* In contrast to APointer above which both points into test_mod and is stored in it. */
int test_mod *APointerInSta;

Pragma directives

ACS Library

#pragma ACS library <string>

<string> is the name of an ACS library to link to at load-time. Objects declared extern not provided during compilation will be searched for inside any ACS libraries specified with this pragma or the -l command line argument.

GDCC FIXED_LITERAL

#pragma GDCC FIXED_LITERAL <ON/OFF>

When ON, all floating point literals that don't end with f/F (for float type), lf/LF (for double type) or llf/LLF (for long double type), will be interpreted as being _Accum/__fixed type. Otherwise, when OFF (the default), floating point literals are handled as normal in C.

GDCC STRENT_LITERAL

#pragma GDCC STRENT_LITERAL <ON/OFF>

When ON, all string literals that aren't suffixed with S (for char[] type), are interpreted as being of __str_ent type. Otherwise, when OFF (the default), string literals are handled as normal in C.

GDCC state

#pragma GDCC state <save/restore>

Saves the current state of set pragmas. Restore restores the last saved state.

⚠️ **GitHub.com Fallback** ⚠️