1

What is the proper way to use and initialise variadic arguments in Zig functions?

fn variadicFunc(val: u8, variadicArg: ...u8) {
  for (variadicArg) |arg| {
    // ... work on the arg
    _ = arg;
  }
}
hippietrail
  • 15,848
  • 18
  • 99
  • 158
Himujjal
  • 1,581
  • 1
  • 14
  • 16

2 Answers2

2

Answering my own question, thanks to Aiz and Hanna from Zig Discord:

The most basic way to write variadicFunction in Zig is to use anytype and anonymous structs:

fn variadicFunc(variadicArg: anytype) {
  for (std.meta.fields(@TypeOf(items)) |field| {
    const value = @field(items, field.name); 
   // work with the value
  }
}

variadicFunc(.{"Hello", 12, .{ Hello } });

But be careful. This will create a binary bloat. Use arrays or slices whenever possible.

Himujjal
  • 1,581
  • 1
  • 14
  • 16
  • 2
    I'm confused by the sample because the argument name is `variadicArg` but that doesn't appear anywhere in the function body. Did you mean to name it `items`? – Joseph Garvin Sep 28 '22 at 05:44
  • @field(items, field.name), field.name must be comptime known. – Chao Jul 30 '23 at 09:43
1

It is possible with anytype and @call.

pub extern "c" fn printf(format: [*:0]const u8, ...) c_int;
const std = @import("std");

fn call_printf(fmt: [*:0]const u8, args: anytype) c_int {
    return @call(.{}, std.c.printf, .{fmt} ++ args);
}

pub fn main() anyerror!void {
    _ = call_printf("All your codebase are belong to %s.", .{"us"});
}
ousttrue
  • 11
  • 1