Variadic argument bindings are not currently possible. The va_list is not part of the function signature in C, but rather a compiler-specific pointer accessed via va_list, va_start and related macros.

For reference, other systems languages like Rust do not support variadic arguments (see https://github.com/rust-lang/rust/issues/44930). While this would be a useful feature, the lack of support in more mature systems languages indicates significant technical challenges.

Related Rust RFC: https://github.com/rust-lang/rust/pull/57760

Additional discussion of the technical challenges can be found at: https://github.com/rust-lang/rust/issues/44930#issuecomment-374609300

Example of desired variadic function binding syntax that is not currently possible: The va_list pointer in C cannot be directly accessed or manipulated from Mojo since it relies on compiler-specific implementation details.

@export(\"count_variadic_args\", ABI=\"C\") # Not supported
alias count_variadic_args = fn (n: ffi.c_int, *args: ffi.c_int) -> ffi.c_int
alias variadic_args_node_count_variadic_args = ExternalFunction[
    'count_variadic_args', 
    count_variadic_args
]

@fieldwise_init
struct variadic_args_node(Copyable, Movable):
    var lib: DLHandle
    var count_variadic_args: variadic_args_node_count_variadic_args.type

    fn __init__(out self):
...
            self.lib = DLHandle(_get_lib_path('libvariadic_args_node.so'))
...
        self.count_variadic_args = variadic_args_node_count_variadic_args            .load(self.lib)

Variadic functions are not currently supported in c_binder_mojo. This is because there is no reliable way to pass unnamed argument lists by value in C. See: https://en.wikipedia.org/wiki/Stdarg.h Best practice is for C APIs to provide equivalent functions that accept va_list arguments instead of variadic arguments. Since c_binder_mojo focuses on binding to existing C code that cannot be modified, variadic functions must be disabled. A potential future solution could involve exposing the va_list pointer directly through a C API, but this would only work for C code that can be modified.

Structs

struct FunctionDeclNode

Aliases

alias name

alias __del__is_trivial

alias __moveinit__is_trivial

alias __copyinit__is_trivial

alias MaybeAnonymous

alias MaybeHasAnonymous

alias MaybeRefersAnonymous

Fields

var storage_class: String

var function_name: String

var function_mangled_name: String

var function_type: String

var is_disabled: Bool

var is_parm_var_decl: Bool

var is_variadic: Bool

var level: Int

var has_pass_by_value_record: Bool

var in_field_decl: Bool

var children_: List[AstNode]

Functions

fn __init__(out self, json_object: Object, level: Int)

fn set_symbol_name(mut self, symbol_name: String)

fn get_symbol_name(self) -> String

fn outer_most_paren_begin(qual_type: String) -> List[Int]

fn outer_most_commas(qual_type: String) -> List[Int]

fn parse_return_type(qual_type: String) -> String

fn parse_parm_var_decls(qual_type: String) -> List[Object]

fn accept_impute(json_object: Object) -> Bool

fn impute(mut json_object: Object)

fn to_string(self, just_code: Bool) -> String

fn children(ref self) -> ref [self] List[AstNode]