API Reference

Each given function aids in iterating over a ztdc_va_list. Currently, the lists are specified to iterate over all arguments where possible, unless compiler optimization or similar interferes with the documented ABI and API constraints of a particular compiler / platform combination. This means that for the following:

An example piece of code with 2 named arguments that go unused.
 1#include <ztd/vargs.hpp>
 2#include <ztd/idk/assert.hpp>
 3
 4double dmul3([[maybe_unused]] int a,
 5             [[maybe_unused]] double b,
 6             ...) {
 7        ztdc_va_list vl;
 8        ztdc_va_start(vl);
 9        int num0    = ztdc_va_arg(vl, int);
10        double num1 = ztdc_va_arg(vl, double);
11        int num2    = ztdc_va_arg(vl, int);
12        ztdc_va_end(vl);
13        return num0 * num1 * num2;
14}
15
16int main() {
17        double result = dmul3(3, 4.5, 5);
18        ZTD_ASSERT(result == 67.5);
19        return 0;
20}

Even the named argument a and b will be iterated over. (A future revision of this library may correct for this, but it is how it is for now.) This means that you should avoid using this when there are arguments present in the list, and therefore wish to execute ``

See the architecture list for supported architectures.

Functions

typedef struct ztdc_va_list ztdc_va_list

The va_list type. Can be used in any scenario where the argument list is empty.

Remark

Currently, only C++ supports such a declaration: Standard C compilers will break on it.

ztdc_va_start(_VL)

Initializes and starts up the iteration of a ... argument list!

Remark

This currently will iterate over arguments that are already presents in the non-variable arguments part of the call, so factor this in appropriately if used with a mix of statically-known and variable arguments!

Mandates

  • The _VL parameter must have been previously initialized by a call to ztdc_va_start.

Cursed?

This call may not work well for everything, since occasionally critical information is missing from just the raw function call. Prefer ztdc_va_arg_in, which takes both a ztdc_va_list and the name of the function it is within.

Parameters
  • _VL[in] A ztdc_va_list (not a pointer to one!).

ztdc_va_start_in(_VL, ...)

Initializes and starts up the iteration of a ... argument list!

Remark

This version uses specialist information from the function prototype to properly adjust the internal implementation. This is important for functions which return large structs that are placed in special positions thanks to Return Value Optimization (RVO), Indirect Struct Return Optimizatino (ISRO), and other behaviors specific to a given platform/ABI/compiler architecture.

Mandates

  • The _VL parameter must have been previously initialized by a call to ztdc_va_start.

  • The ... token parameters must form a complete, non-overloaded function name (qualified or unqualified) which can have its type (decltype(__VA_ARGS__)) taken. The behavior is undefined if this is not the function that is actually calling this.

Parameters
  • _VL[in] A ztdc_va_list (not a pointer to one!).

  • ...[in] The function name this is being called from.

ztdc_va_arg(_VL, _TYPE)

Initializes and starts up the iteration of a ... argument list!

Remark

This currently will iterate over arguments that are already presents in the non-variable arguments part of the call, so factor this in appropriately if used with a mix of statically-known and variable arguments!

Mandates

  • _TYPE shall not be a reference type (pointer types are fine).

  • The _VL parameter must have been previously initialized by a call to ztdc_va_start.

Cursed?

Parameters
  • _VL[in] A ztdc_va_list (not a pointer to one!).

  • _TYPE[in] The type to pass in. Must not be a reference type.

ztdc_va_end(_VL)

Ends the iteration of a ztdc_va_list.

Mandates

  • The _VL parameter must have been previously initialized by a call to ztdc_va_start.

Cursed?

Parameters
  • _VL[in] A ztdc_va_list (not a pointer to one!).