Standard Defines module

This module provides various #defines for performing basic tasks and macro-related functions, and some small meta-programming functionality

Defines

#define CNX_VERSION_MAJOR
The major portion of the version number of the Cnx library e.g. in "x.y.z", the "x" part.
#define CNX_VERSION_MINOR
The minor portion of the version number of the Cnx library e.g. in "x.y.z", the "y" part.
#define CNX_VERSION_PATCH
The patch portion of the version number of the Cnx library e.g. in "x.y.z", the "z" part.
#define CNX_VERSION
The version number of the Cnx library parsed into a single 32-bit integer Each portion of the version number will take 8 bits in the resulting integer, with the total parsed version number comprising of the lower 24 bits. The layout is 00000000xxxxxxxxyyyyyyyyzzzzzzzz where:
#define UNIQUE_VAR(x)
Provides a semi-unique variable name with x as a prefix.
#define typeof(value)
Returns the type of the given expression.
#define alignof(type)
Returns the alignment size in bytes of the given type.
#define cnx_disable(message)
Disables the preceding/following function at compile-time.
#define cnx_disable_if(condition, message)
Disables the preceding/following function at compile-time, based on the given condition
#define cnx_enable_if(condition, message)
Enables the preceding/following function at compile-time, based on the given condition
#define cnx_warn_if(condition, message)
Emits a warning for using the preceding/following function at compile-time, based on the given condition
#define unreachable()
Specify that the given scope is unreachable.
#define always_inline
Specify that the following function should always be inlined.
#define not_null(...)
Attribute to specify that the function arguments in the indicated positions (1-based indices) should not be nullptr.
#define returns_not_null
Attribute to specify that the pointer the function returns will never be nullptr.
#define nodiscard
Attribute to specify that the return value of the tagged function should not be discarded.
#define maybe_unused
Attribute to specify that a value may be unused or discarded.
#define scoped(scope_end_func)
Use this macro to declare a variable that will have a cleanup function called on it at scope end.
#define move(self)
Moves self into the assigned-to or bound-to variable/parameter/etc.
#define let
Declare a variable with let to create a const variable with inferred type.
#define let_mut
Declare a variable with let_mut to create a mutable variable with inferred type.
#define loop
Use to declare an infinite loop, equivalent to while(true) or for(;;)
#define Ptr(T)
shorthand for writing T_ptr, used for generating typedef names needed for macros that require an alphanumeric name for T*
#define Ref(T)
shorthand for writing T_ptr, used for generating typedef names needed for macros that require an alphanumeric name for T* when implying reference-like semantics
#define ConstRef(T)
shorthand for writing const_T_ptr, used for generating typedef names needed for macros that require an alphanumeric name for const T* when implying reference-like semantics
#define ranged_for(var, begin, end)
Shorthand for writing a for loop.
#define ignore(...)
Ignores the given parameters.
#define static_cast(Type)
Casts to the type Type.
#define narrow_cast(Type)
Casts to the type Type.
#define const_cast(Type)
Casts to the type Type.
#define false
Define the boolean constant false
#define true
Define the boolean constant true
#define BEGIN_SCOPED_VARIABLES()
Creates a scope for wrapping an arbitrary number of variable declarations in with subsequent uses of SCOPE_VARIABLE(). The net scope will make up one single compound-statement.
#define SCOPE_VARIABLE(...)
Wraps the given variable declaration(s) in a containing scope. The scope must have been previously initiated with BEGIN_SCOPED_VARIABLES(). Variable declarations must be compatible with the initialization statement (aka the "clause" statement) in a for loop. The net scope will make one a single compound-statement.

Define documentation

#define CNX_VERSION_MAJOR

The major portion of the version number of the Cnx library e.g. in "x.y.z", the "x" part.

#define CNX_VERSION_MINOR

The minor portion of the version number of the Cnx library e.g. in "x.y.z", the "y" part.

#define CNX_VERSION_PATCH

The patch portion of the version number of the Cnx library e.g. in "x.y.z", the "z" part.

#define CNX_VERSION

The version number of the Cnx library parsed into a single 32-bit integer Each portion of the version number will take 8 bits in the resulting integer, with the total parsed version number comprising of the lower 24 bits. The layout is 00000000xxxxxxxxyyyyyyyyzzzzzzzz where:

  • xxxxxxxx comprises CNX_VERSION_MAJOR
  • yyyyyyyy comprises CNX_VERSION_MINOR
  • zzzzzzzz comprises CNX_VERSION_PATCH

#define UNIQUE_VAR(x)

Provides a semi-unique variable name with x as a prefix.

Parameters
x - The prefix for the variable name
Returns The resulting variable name

Useful inside macros to prevent name-collision and/or shadowing. Does not create a truly unique variable name, so must be used with some care, but is good for most circumstances. The produced name is not cachable/storable and depends on __LINE__, so cannot be re-referenced later in a file, so this is only useful for one-time-use names or for use inside macros

#define typeof(value)

Returns the type of the given expression.

Parameters
value - The expression to get the resulting type of
Returns the type of the expression

#define alignof(type)

Returns the alignment size in bytes of the given type.

Parameters
type - The type to get the alignment of
Returns the alignment size of the type

#define cnx_disable(message)

Disables the preceding/following function at compile-time.

Parameters
message - The error message for the compiler to show the user

Forces a compiler error with the given message if the associated function is called.

#define cnx_disable_if(condition, message)

Disables the preceding/following function at compile-time, based on the given condition

Parameters
condition - The condition indicating whether the function should be disabled
message - The error message for the compiler to show the user

Forces a compiler error with the given message if the associated function is called and condition evaluates to true. condition can include parameters to the function if this is applied as a postfix, thus enabling things like:

int func(int a, int b) cnx_disable_if(a < b, "a must be greater than b") {
    // do things here...
}

#define cnx_enable_if(condition, message)

Enables the preceding/following function at compile-time, based on the given condition

Parameters
condition - The condition indicating whether the function should be enabled
message - The error message for the compiler to show the user

Forces a compiler error with the given message if the associated function is called and condition evaluates to false. condition can include parameters to the function if this is applied as a postfix, thus enabling things like:

int func(int a, int b) cnx_enable_if(a > b, "a must be greater than b") {
    // do things here...
}

#define cnx_warn_if(condition, message)

Emits a warning for using the preceding/following function at compile-time, based on the given condition

Parameters
condition - The condition indicating whether using the function should cause a warning
message - The error message for the compiler to show the user

Forces a compiler warning with the given message if the associated function is called and condition evaluates to true. condition can include parameters to the function if this is applied as a postfix, thus enabling things like:

int func(int a, int b) cnx_warn_if(a < b, "a must be greater than b") {
    // do things here...
}

#define unreachable()

Specify that the given scope is unreachable.

#define always_inline

Specify that the following function should always be inlined.

#define not_null(...)

Attribute to specify that the function arguments in the indicated positions (1-based indices) should not be nullptr.

Example: [[not_null(1, 2)]] int func(void* data, void* res, int value);

#define returns_not_null

Attribute to specify that the pointer the function returns will never be nullptr.

Example [[returns_not_null]] void* func(void* data, int value);

#define nodiscard

Attribute to specify that the return value of the tagged function should not be discarded.

Example __attr(nodiscard) my_important_return_type my_important_function(void);

#define maybe_unused

Attribute to specify that a value may be unused or discarded.

Example void my_important_function(__attr(maybe_unused) i32 my_int);

#define scoped(scope_end_func)

Use this macro to declare a variable that will have a cleanup function called on it at scope end.

Parameters
scope_end_func - The function to call on the declared variable when it goes out of scope

This allows for automatic RAII-style handling of resources by guaranteeing that the variable will have whatever cleanup needs performed on it completed at scope end.

#define move(self)

Moves self into the assigned-to or bound-to variable/parameter/etc.

Parameters
self - The object to move
Returns the moved value

This brings some semblance of C++ or Rust style move semantics to C

#define let

Declare a variable with let to create a const variable with inferred type.

let declares the variable as const and infers the type from the value being assigned to it. A variable declared with let will be const and thus read only. let should be preferred for all variable declarations, whenever possible.

#define let_mut

Declare a variable with let_mut to create a mutable variable with inferred type.

let_mut declares the variable and infers the type from the value being assigned to it. A variable declared with let_mut will be mutable and thus able to be modified. let_mut should be preferred for all variable declarations when mutability is required, whenever possible.

#define loop

Use to declare an infinite loop, equivalent to while(true) or for(;;)

#define Ptr(T)

shorthand for writing T_ptr, used for generating typedef names needed for macros that require an alphanumeric name for T*

Parameters
T - The type to generate a name for "pointer to" for

#define Ref(T)

shorthand for writing T_ptr, used for generating typedef names needed for macros that require an alphanumeric name for T* when implying reference-like semantics

Parameters
T - The type to generate a name for "pointer to" for

#define ConstRef(T)

shorthand for writing const_T_ptr, used for generating typedef names needed for macros that require an alphanumeric name for const T* when implying reference-like semantics

Parameters
T - The type to generate a name for "pointer to const" for

#define ranged_for(var, begin, end)

Shorthand for writing a for loop.

Parameters
var - The name of the loop variable
begin - The initial value for var
end - The stop value for var

Expands to a for loop with loop variable var initialized to begin and ending at end non-inclusive. Example:

// loops over the range [0, 10)
ranged_for(i, 0, 10) {
    // do something here ...
}

#define ignore(...)

Ignores the given parameters.

Use to ignore the passed parameters, preventing compiler warnings for parameters that are intentionally unused

#define static_cast(Type)

Casts to the type Type.

Parameters
Type - The type to cast to

This should be preferred for making non-lossy conversions between types (eg i8 to i32 or void* to cstring)

#define narrow_cast(Type)

Casts to the type Type.

Parameters
Type - The type to cast to

This should be preferred for making lossy conversions between types (eg i32 to f32 or u64 to i64)

#define const_cast(Type)

Casts to the type Type.

Parameters
Type - The type to cast to

This should be preferred when casting away const-ness of a value (eg const_cstring to cstring)

#define false

Define the boolean constant false

Redefine false as casted to bool to enforce correct type inference with let and let_mut

#define true

Define the boolean constant true

Redefine true as casted to bool to enforce correct type inference with let and let_mut

#define BEGIN_SCOPED_VARIABLES()

Creates a scope for wrapping an arbitrary number of variable declarations in with subsequent uses of SCOPE_VARIABLE(). The net scope will make up one single compound-statement.

#define SCOPE_VARIABLE(...)

Wraps the given variable declaration(s) in a containing scope. The scope must have been previously initiated with BEGIN_SCOPED_VARIABLES(). Variable declarations must be compatible with the initialization statement (aka the "clause" statement) in a for loop. The net scope will make one a single compound-statement.