Revision [24167]

This is an old revision of ProPgVariadicArguments made by fxm on 2020-08-02 11:20:59.


Variadic Arguments

Allows a procedure to accept a variable number of arguments.

Normal procedures take a fixed number of arguments. When such a procedure is defined, the data-type of each argument is specified.
Every call to this procedure should supply the expected number of arguments, with types that can be converted to the specified ones.

Variadic arguments allow to define procedures which accept a variable number of arguments.
Support for variadic procedures differs widely among programming languages.

Variadic procedures can expose type-safety problems because the language support for variadic procedures is not type-safe:
- it allows to extract any number of arguments from the stack or elsewhere,
- and this while defining their types from entered user parameters.
If the variable arguments are all of same type or compatible with the same type, a dynamically sized array can be passed instead, but this requires slightly more work at the caller level.

Syntax for declaring and calling variadic procedures
The ellipsis "..." (three dots), as last parameter, is used in procedure declarations (and definitions) to indicate a variable length argument list:
- A first fixed parameter (at least) must always be specified:
The fixed parameters(s) can provide information about how many variadic arguments there are, by an unspecified mechanism.
Otherwise a terminal argument can be added in the variable length argument list, but this reserves a special argument value forbidden to the useful variadic arguments.
(if one choose to pass the variable arguments all by pointer, in this case an obvious terminal argument is the null pointer)
- The procedure must be called with the C calling convention cdecl.
- A variadic procedure can never be overloaded:
so this also excludes its use in UDT for constructors and properties,
but otherwise it can be declared abstract or virtual or even overriding.
- For variadic procedure members, the implicit passed this parameter is not taken into account as first fixed parameter (at least one explicit fixed parameter must always be specified).

Declaration syntax
declare { sub | function } proc_name cdecl ( param_list, ... ) { | [ byref ] as return_type }
Parenthesized comma-separated list of fixed parameters.
The return type of a Function.
The name or symbol of the procedure.

Calling syntax
There is nothing special to do for calling a variadic procedure.
The procedure is simply called by writing the arguments for the fixed parameters, followed by the additional variable arguments, as usual.

Only numeric types and pointers are supported as variable arguments:
- All bytes and shorts passed on variable arguments are implicitly converted to integers.
- All singles passed on variable arguments are implicitly converted to doubles.
- Strings (or Wstrings) can be directly passed by user, in which case a Zstring Ptr (or a Wstring Ptr) to the string (or the wstring) data is taken into account as internal passed argument.

Two ' va_* ' support's keywords families to retrieve the variable arguments in procedure body
Variable arguments my use the stack, or registers, as per the normal conventions for the compiler:
- For some compilers in the past, while registers were used for normal procedures, stack was (always) used for variadic procedures.
- The gcc compiler family all seem to agree that the call signatures for variadic procedures are exactly the same as properly specified procedures. This means that some of the variable arguments may be in registers and some may be on the stack if there are too many.

The va_* support's keywords create an interface to retrieve these variable arguments in procedure body:
- The first FreeBASIC va_* support's keywords family developed have been the FB's va_* support's keywords family:
These FB's va_* support's keywords are very x86-specific and only work with the gas for x86 GAS assembly backend, because using a pointer to the argument stack.
These FB's va_* support's keywords don't work on all targets (like 64-bit) because arguments can be passed to procedures in cpu registers.
These FB's va_* support's keywords are now deprecated but kept for backwards compatibility on some targets.
- More recently, a FreeBASIC update added a new support's keywords family for variadic procedure argument lists:
This is the C's va_* support's keywords family compatible for all target platforms.
These C's va_* support's keywords are now recommended for all new coding.

See also:
Back to Programmer's Guide
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki phatcode