Skip to content
CryoCryo home
Stdlibcore

varargs

import std::core::varargs; — in the prelude · source

Types

VaArgs

type struct VaArgs {
    ptr: void*;

    static new(va: void*) -> VaArgs;
    as_ptr(&this) -> void*;

    ![implicit]
    next<T>(&this) -> T
    where T: VaArg;
}

A function declared with a trailing args... bucket mirrors C's variadic calling convention, which keeps it ABI-compatible for printf-style interop. The compiler emits va_start/va_end around the body and binds args to the raw va_list. VaArgs wraps that pointer so you can read typed values without hand-rolling va_arg:

function logf(fmt: string, args...) -> void {
    mut va: VaArgs = VaArgs::new(args);
    const count: i32 = va.next();          // T inferred as i32
    const name: string = va.next();
}

as_ptr() hands back the raw va_list for forwarding the rest to a C v*-family function such as vfprintf.

Two limits come from C varargs and no wrapper can fix them. It is not count-safe — nothing records how many arguments were passed or their types, so the callee has to know out of band (a format string, a leading count, a sentinel). And the default argument promotions apply: a variadic call promotes i8, i16, and boolean to i32, and f32 to f64. VaArg is therefore implemented only for the promoted set, and va.next::<i8>() is a compile error by design — read it as i32 and narrow.

Properties

PropertyType
ptrvoid*

Constructors

static new(va: void*) -> VaArgs;

Wrap a variadic body's args bucket: VaArgs::new(args). va is the raw va_list pointer the compiler binds for the args... parameter.

Methods

as_ptr(&this) -> void*;

The raw va_list pointer, for forwarding the remaining arguments to a C v*-family function (vfprintf, vsnprintf, ...). Equivalent to passing the original args identifier.

![implicit] next<T>(&this) -> T where T: VaArg;

Read the next variadic argument as T (one of the promoted scalar types), advancing the list. ![implicit] lets the type be recovered from the call's expected type, so const n: i64 = va.next(); works; va.next<i64>() is the explicit form.

Trait implementations

implement trait Copy for VaArgs
implement trait Drop for VaArgs

VaArg

type trait VaArg {
    static __pluck(p: void*) -> This;
}

The trait next<T> dispatches through. It is implemented for exactly the types that survive C's default argument promotions, which is why va.next::<i8>() is a compile error rather than a silent misread.

Constructors

static __pluck(p: void*) -> This;

Read the next argument of type This from the va_list p points at, advancing it. p is the raw va_list pointer (VaArgs::as_ptr).

Implementors

implement trait VaArg for i32
implement trait VaArg for u32
implement trait VaArg for i64
implement trait VaArg for u64
implement trait VaArg for f64
implement trait VaArg for string