aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-12-18 16:24:13 -0500
committerGitHub <noreply@github.com>2022-12-18 16:24:13 -0500
commitaca9c74e80e106309b9783ff251ab0cdd3fb9626 (patch)
tree16c65995ac6d3b434af61c4cd61a191b81dd93a0 /doc
parentd93edadead45e447e6bc16c0934a3031a06d0fd8 (diff)
parent9bb1104e373dec192fb2a22d48b023330ddbaeae (diff)
downloadzig-aca9c74e80e106309b9783ff251ab0cdd3fb9626.tar.gz
zig-aca9c74e80e106309b9783ff251ab0cdd3fb9626.zip
Merge pull request #13914 from Vexu/variadic
implement defining C variadic functions
Diffstat (limited to 'doc')
-rw-r--r--doc/langref.html.in59
1 files changed, 53 insertions, 6 deletions
diff --git a/doc/langref.html.in b/doc/langref.html.in
index 08fa59746d..04755d00ec 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -8088,6 +8088,35 @@ test "main" {
{#see_also|Import from C Header File|@cImport|@cDefine|@cInclude#}
{#header_close#}
+ {#header_open|@cVaArg#}
+ <pre>{#syntax#}@cVaArg(operand: *std.builtin.VaList, comptime T: type) T{#endsyntax#}</pre>
+ <p>
+ Implements the C macro {#syntax#}va_arg{#endsyntax#}.
+ </p>
+ {#see_also|@cVaCopy|@cVaEnd|@cVaStart#}
+ {#header_close#}
+ {#header_open|@cVaCopy#}
+ <pre>{#syntax#}@cVaCopy(src: *std.builtin.VaList) std.builtin.VaList{#endsyntax#}</pre>
+ <p>
+ Implements the C macro {#syntax#}va_copy{#endsyntax#}.
+ </p>
+ {#see_also|@cVaArg|@cVaEnd|@cVaStart#}
+ {#header_close#}
+ {#header_open|@cVaEnd#}
+ <pre>{#syntax#}@cVaEnd(src: *std.builtin.VaList) void{#endsyntax#}</pre>
+ <p>
+ Implements the C macro {#syntax#}va_end{#endsyntax#}.
+ </p>
+ {#see_also|@cVaArg|@cVaCopy|@cVaStart#}
+ {#header_close#}
+ {#header_open|@cVaStart#}
+ <pre>{#syntax#}@cVaStart() std.builtin.VaList{#endsyntax#}</pre>
+ <p>
+ Implements the C macro {#syntax#}va_start{#endsyntax#}. Only valid inside a variadic function.
+ </p>
+ {#see_also|@cVaArg|@cVaCopy|@cVaEnd#}
+ {#header_close#}
+
{#header_open|@divExact#}
<pre>{#syntax#}@divExact(numerator: T, denominator: T) T{#endsyntax#}</pre>
<p>
@@ -10802,14 +10831,32 @@ test "variadic function" {
}
{#code_end#}
<p>
- Non extern variadic functions are currently not implemented, but there
- is an accepted proposal. See <a href="https://github.com/ziglang/zig/issues/515">#515</a>.
+ Variadic functions can be implemented using {#link|@cVaStart#}, {#link|@cVaEnd#}, {#link|@cVaArg#} and {#link|@cVaCopy#}
</p>
- {#code_begin|obj_err|non-extern function is variadic#}
-export fn printf(format: [*:0]const u8, ...) c_int {
- _ = format;
+ {#code_begin|test|defining_variadic_function#}
+const std = @import("std");
+const testing = std.testing;
+const builtin = @import("builtin");
- return 0;
+fn add(count: c_int, ...) callconv(.C) c_int {
+ var ap = @cVaStart();
+ defer @cVaEnd(&ap);
+ var i: usize = 0;
+ var sum: c_int = 0;
+ while (i < count) : (i += 1) {
+ sum += @cVaArg(&ap, c_int);
+ }
+ return sum;
+}
+
+test "defining a variadic function" {
+ // Variadic functions are currently disabled on some targets due to miscompilations.
+ if (builtin.cpu.arch == .aarch64 and builtin.os.tag != .windows and builtin.os.tag != .macos) return error.SkipZigTest;
+ if (builtin.cpu.arch == .x86_64 and builtin.os.tag == .windows) return error.SkipZigTest;
+
+ try std.testing.expectEqual(@as(c_int, 0), add(0));
+ try std.testing.expectEqual(@as(c_int, 1), add(1, @as(c_int, 1)));
+ try std.testing.expectEqual(@as(c_int, 3), add(2, @as(c_int, 1), @as(c_int, 2)));
}
{#code_end#}
{#header_close#}