### Shell Commands for Zig `print` Example Source: https://ziglang.org/documentation/0.16.0 Shows the shell commands to compile and run the Zig `print` example. This is necessary to see the output generated by the `print` function. ```shell $ `zig build-exe print.zig` $ `./print` ``` -------------------------------- ### Running Inline Function Example Source: https://ziglang.org/documentation/0.16.0 Shell commands to build and run the Zig program demonstrating inline functions. ```shell $ `zig build-exe inline_call.zig` $ `./inline_call` runtime a = 1200 b = 34 ``` -------------------------------- ### Compiling and Running C Import Example Source: https://ziglang.org/documentation/0.16.0 Shows the shell commands to compile a Zig file that imports C headers and then execute the compiled program. ```shell $ `zig build-exe cImport_builtin.zig -lc` $ `./cImport_builtin` hello ``` -------------------------------- ### Run Zig Standard Library Documentation Source: https://ziglang.org/documentation/0.16.0 This command renders the Zig Standard Library documentation locally. Ensure Zig is installed and accessible in your PATH. ```Shell zig std ``` -------------------------------- ### Basic Hello World in Zig Source: https://ziglang.org/documentation/0.16.0 A simple 'Hello, World!' program demonstrating standard output writing. This example uses `std.io.File.stdout().writeStreamingAll` for output. ```Zig const std = @import("std"); pub fn main(init: std.process.Init) !void { try std.io.File.stdout().writeStreamingAll(init.io, "Hello, World!\n"); } ``` -------------------------------- ### List Preopens with WASI Source: https://ziglang.org/documentation/0.16.0 This example demonstrates how to access and log the preopened file descriptors available in a WASI environment. It uses `std.fs.wasi.Preopens` to retrieve the list of preopens provided by the runtime. ```zig const std = @import("std"); pub fn main(init: std.process.Init) void { for (init.preopens.map.keys(), 0..) |preopen, i| { std.log.info("{d}: {s}", .{ i, preopen }); } } ``` ```shell $ zig build-exe wasi_preopens.zig -target wasm32-wasi ``` ```shell $ wasmtime --dir=. wasi_preopens.wasm 0: stdin 1: stdout 2: stderr 3: . ``` -------------------------------- ### Vector Destructuring Example Source: https://ziglang.org/documentation/0.16.0 Demonstrates destructuring a vector to extract individual elements and rearrange them into a new vector. This example emulates the `punpckldq` instruction. ```zig const print = @import("std").debug.print; // emulate punpckldq pub fn unpack(x: @Vector(4, f32), y: @Vector(4, f32)) @Vector(4, f32) { const a, const c, _, _ = x; const b, const d, _, _ = y; return .{ a, b, c, d }; } pub fn main() void { const x: @Vector(4, f32) = .{ 1.0, 2.0, 3.0, 4.0 }; const y: @Vector(4, f32) = .{ 5.0, 6.0, 7.0, 8.0 }; print("{}", .{unpack(x, y)}); } ``` -------------------------------- ### Zig Test Execution for for Loop Examples Source: https://ziglang.org/documentation/0.16.0 Shell commands to test the Zig code examples for for loops, labeled loops, and inline for loops. ```shell $ `zig test test_for.zig` 1/4 test_for.test.for basics...OK 2/4 test_for.test.multi object for...OK 3/4 test_for.test.for reference...OK 4/4 test_for.test.for else...OK All 4 tests passed. ``` ```shell $ `zig test test_for_nested_break.zig` 1/2 test_for_nested_break.test.nested break...OK 2/2 test_for_nested_break.test.nested continue...OK All 2 tests passed. ``` ```shell $ `zig test test_inline_for.zig` 1/1 test_inline_for.test.inline for loop...OK All 1 tests passed. ``` -------------------------------- ### Zig Test Execution for Coercion Examples Source: https://ziglang.org/documentation/0.16.0 Shows the output of running Zig tests for the type coercion examples, confirming that all tests passed. ```shell $ `zig test test_coerce_slices_arrays_and_pointers.zig` 1/8 test_coerce_slices_arrays_and_pointers.test.*const [N]T to []const T...OK 2/8 test_coerce_slices_arrays_and_pointers.test.*const [N]T to E![]const T...OK 3/8 test_coerce_slices_arrays_and_pointers.test.*const [N]T to ?[]const T...OK 4/8 test_coerce_slices_arrays_and_pointers.test.*[N]T to []T...OK 5/8 test_coerce_slices_arrays_and_pointers.test.*[N]T to [*]T...OK 6/8 test_coerce_slices_arrays_and_pointers.test.*[N]T to ?[*]T...OK 7/8 test_coerce_slices_arrays_and_pointers.test.*T to *[1]T...OK 8/8 test_coerce_slices_arrays_and_pointers.test.[:x]T to [*:x]T...OK All 8 tests passed. ``` ```shell $ `zig test test_coerce_optionals.zig` 1/1 test_coerce_optionals.test.coerce to optionals...OK All 1 tests passed. ``` ```shell $ `zig test test_coerce_optional_wrapped_error_union.zig` 1/1 test_coerce_optional_wrapped_error_union.test.coerce to optionals wrapped in error union...OK All 1 tests passed. ``` ```shell $ `zig test test_coerce_to_error_union.zig` 1/1 test_coerce_to_error_union.test.coercion to error unions...OK All 1 tests passed. ``` -------------------------------- ### Building and Running Destructuring Example Source: https://ziglang.org/documentation/0.16.0 This shell command first builds the `destructuring_vectors.zig` program into an executable and then runs it to display the output of the vector destructuring function. ```shell $ `zig build-exe destructuring_vectors.zig` $ `./destructuring_vectors` { 1, 5, 2, 6 } ``` -------------------------------- ### Zig Build Command for Float Mode Example Source: https://ziglang.org/documentation/0.16.0 Shows the shell command to build a Zig object file with optimizations enabled, which is necessary for testing floating-point mode differences. ```shell `zig build-obj float_mode_obj.zig -O ReleaseFast` ``` -------------------------------- ### Variable Alignment Example Source: https://ziglang.org/documentation/0.16.0 Demonstrates how to check and enforce alignment for variables using @alignOf and explicit alignment specifiers. ```zig const std = @import("std"); const builtin = @import("builtin"); const expect = std.testing.expect; const expectEqual = std.testing.expectEqual; test "variable alignment" { var x: i32 = 1234; try expectEqual(*i32, @TypeOf(&x)); try expect(@intFromPtr(&x) % @alignOf(i32) == 0); // The implicitly-aligned pointer can be coerced to be explicitly-aligned to // the alignment of the underlying type `i32`: const ptr: *align(@alignOf(i32)) i32 = &x; try expectEqual(1234, ptr.*); } ``` -------------------------------- ### Declaring and Using Zig Structs Source: https://ziglang.org/documentation/0.16.0 Demonstrates the declaration of structs, instantiation of struct instances, and the definition and usage of struct methods. Includes examples of empty structs and accessing struct-namespaced variables. ```zig const Point = struct { x: f32, y: f32, }; const p: Point = .{ .x = 0.12, .y = 0.34, }; const Vec3 = struct { x: f32, y: f32, z: f32, pub fn init(x: f32, y: f32, z: f32) Vec3 { return Vec3{ .x = x, .y = y, .z = z, }; } pub fn dot(self: Vec3, other: Vec3) f32 { return self.x * other.x + self.y * other.y + self.z * other.z; } }; test "dot product" { const v1 = Vec3.init(1.0, 0.0, 0.0); const v2 = Vec3.init(0.0, 1.0, 0.0); try expectEqual(0.0, v1.dot(v2)); try expectEqual(0.0, Vec3.dot(v1, v2)); } const Empty = struct { pub const PI = 3.14; }; test "struct namespaced variable" { try expectEqual(3.14, Empty.PI); try expectEqual(0, @sizeOf(Empty)); const does_nothing: Empty = .{}; _ = does_nothing; } fn setYBasedOnX(x: *f32, y: f32) void { const point: *Point = @fieldParentPtr("x", x); point.y = y; } test "field parent pointer" { var point = Point{ .x = 0.1234, .y = 0.5678, }; setYBasedOnX(&point.x, 0.9); try expectEqual(0.9, point.y); } fn LinkedList(comptime T: type) type { return struct { pub const Node = struct { prev: ?*Node, next: ?*Node, data: T, }; first: ?*Node, last: ?*Node, len: usize, }; } test "linked list" { try expectEqual(LinkedList(i32), LinkedList(i32)); const list = LinkedList(i32){ .first = null, .last = null, .len = 0, }; try expectEqual(0, list.len); const ListOfInts = LinkedList(i32); try expectEqual(LinkedList(i32), ListOfInts); var node = ListOfInts.Node{ .prev = null, .next = null, .data = 1234, }; const list2 = LinkedList(i32){ .first = &node, .last = &node, .len = 1, }; try expectEqual(1234, list2.first.?.data); } const expectEqual = @import("std").testing.expectEqual; ``` -------------------------------- ### CLI Application with ArenaAllocator Source: https://ziglang.org/documentation/0.16.0 Example of a command-line application using ArenaAllocator for managing allocations. Memory is freed automatically when the arena is deinitialized. ```zig const std = @import("std"); pub fn main() !void { var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); defer arena.deinit(); const allocator = arena.allocator(); const ptr = try allocator.create(i32); std.debug.print("ptr={*}\n", .{ptr}); } ``` -------------------------------- ### Example of Builtin Package Contents Source: https://ziglang.org/documentation/0.16.0 This snippet illustrates the various compile-time constants available by importing the "builtin" package, including Zig version, target details, and build configurations. ```zig const std = @import("std"); /// Zig version. When writing code that supports multiple versions of Zig, prefer /// feature detection (i.e. with `@hasDecl` or `@hasField`) over version checks. pub const zig_version = std.SemanticVersion.parse(zig_version_string) catch unreachable; pub const zig_version_string = "0.16.0-dev.3132+fd2718f82"; pub const zig_backend = std.builtin.CompilerBackend.stage2_x86_64; pub const output_mode: std.builtin.OutputMode = .Exe; pub const link_mode: std.builtin.LinkMode = .static; pub const unwind_tables: std.builtin.UnwindTables = .async; pub const is_test = false; pub const single_threaded = false; pub const abi: std.Target.Abi = .gnu; pub const cpu: std.Target.Cpu = .{ .arch = .x86_64, .model = &std.Target.x86.cpu.znver4, .features = std.Target.x86.featureSet(&.{ ."64bit", .adx, .aes, .allow_light_256_bit, .avx, .avx2, .avx512bf16, .avx512bitalg, .avx512bw, .avx512cd, .avx512dq, .avx512f, .avx512ifma, .avx512vbmi, .avx512vbmi2, .avx512vl, .avx512vnni, .avx512vpopcntdq, .bmi, .bmi2, .branchfusion, .clflushopt, .clwb, .clzero, .cmov, .crc32, .cx16, .cx8, .evex512, .f16c, .fast_15bytenop, .fast_bextr, .fast_dpwssd, .fast_imm16, .fast_lzcnt, .fast_movbe, .fast_scalar_fsqrt, .fast_scalar_shift_masks, .fast_variable_perlane_shuffle, .fast_vector_fsqrt, .fma, .fsgsbase, .fsrm, .fxsr, .gfni, .idivq_to_divl, .invpcid, .lzcnt, .macrofusion, .mmx, .movbe, .mwaitx, .nopl, .pclmul, .pku, .popcnt, .prfchw, .rdpid, .rdpru, .rdrnd, .rdseed, .sahf, .sbb_dep_breaking, .sha, .shstk, .smap, .smep, .sse, .sse2, .sse3, .sse4_1, .sse4_2, .sse4a, .ssse3, .vaes, .vpclmulqdq, .vzeroupper, .wbnoinvd, .x87, .xsave, .xsavec, .xsaveopt, .xsaves, }), }; pub const os: std.Target.Os = .{ .tag = .linux, .version_range = .{.linux = .{ .range = .{ .min = .{ .major = 6, .minor = 18, .patch = 9, }, .max = .{ .major = 6, .minor = 18, .patch = 9, }, }, .glibc = .{ .major = 2, .minor = 39, .patch = 0, }, .android = 29, }}, }; pub const target: std.Target = .{ .cpu = cpu, .os = os, .abi = abi, .ofmt = object_format, .dynamic_linker = .init("/nix/store/vr7ds8vwbl2fz7pr221d5y0f8n9a5wda-glibc-2.40-218/lib/ld-linux-x86-64.so.2"), }; pub const object_format: std.Target.ObjectFormat = .elf; pub const mode: std.builtin.OptimizeMode = .Debug; pub const link_libc = false; pub const link_libcpp = false; pub const have_error_return_tracing = true; pub const valgrind_support = true; pub const sanitize_thread = false; pub const fuzz = false; pub const position_independent_code = false; pub const position_independent_executable = false; pub const strip_debug_info = false; pub const code_model: std.builtin.CodeModel = .default; pub const omit_frame_pointer = false; ``` -------------------------------- ### Basic `print` Usage in Zig Source: https://ziglang.org/documentation/0.16.0 Demonstrates how to use the `std.debug.print` function to output formatted strings and numbers to the console. This example requires compilation and execution using the Zig toolchain. ```zig const print = @import("std").debug.print; const a_number: i32 = 1234; const a_string = "foobar"; pub fn main() void { print("here is a string: '{s}' here is a number: {}\\n", .{ a_string, a_number }); } ``` -------------------------------- ### Error Return Trace Example Source: https://ziglang.org/documentation/0.16.0 Demonstrates how error return traces show the full path of an error, including intermediate error handling and re-throwing. This code highlights the difference between an error return trace and a stack trace. ```zig pub fn main() !void { try foo(12); } fn foo(x: i32) !void { if (x >= 5) { try bar(); } else { try bang2(); } } fn bar() !void { if (baz()) { try quux(); } else |err| switch (err) { error.FileNotFound => try hello(), } } fn baz() !void { try bang1(); } fn quux() !void { try bang2(); } fn hello() !void { try bang2(); } fn bang1() !void { return error.FileNotFound; } fn bang2() !void { return error.PermissionDenied; } ``` ```shell $ `zig build-exe error_return_trace.zig` $ `./error_return_trace` error: PermissionDenied /home/andy/src/zig/doc/langref/error_return_trace.zig:34:5: 0x11d4b9c in bang1 (error_return_trace.zig) return error.FileNotFound; ^ /home/andy/src/zig/doc/langref/error_return_trace.zig:22:5: 0x11d4bfc in baz (error_return_trace.zig) try bang1(); ^ /home/andy/src/zig/doc/langref/error_return_trace.zig:38:5: 0x11d4c3c in bang2 (error_return_trace.zig) return error.PermissionDenied; ^ /home/andy/src/zig/doc/langref/error_return_trace.zig:30:5: 0x11d4d1c in hello (error_return_trace.zig) try bang2(); ^ /home/andy/src/zig/doc/langref/error_return_trace.zig:17:31: 0x11d4e2a in bar (error_return_trace.zig) error.FileNotFound => try hello(), ^ /home/andy/src/zig/doc/langref/error_return_trace.zig:7:9: 0x11d4f0a in foo (error_return_trace.zig) try bar(); ^ /home/andy/src/zig/doc/langref/error_return_trace.zig:2:5: 0x11d5011 in main (error_return_trace.zig) try foo(12); ^ ``` -------------------------------- ### Zig 0-Terminated Slice Example Source: https://ziglang.org/documentation/0.16.0 Demonstrates the creation and usage of a 0-terminated slice of bytes. This slice guarantees a null byte at the end, and its length is accessible at runtime. ```zig const std = @import("std"); const expectEqual = std.testing.expectEqual; test "0-terminated slice" { const slice: [:0]const u8 = "hello"; try expectEqual(5, slice.len); try expectEqual(0, slice[5]); } ``` -------------------------------- ### Zig Switch Continue Example Source: https://ziglang.org/documentation/0.16.0 Demonstrates the usage of `continue` with a labeled switch statement in Zig. The `continue` keyword can target a labeled switch and optionally take an operand to re-evaluate the switch. ```zig const std = @import("std"); test "switch continue" { sw: switch (@as(i32, 5)) { 5 => continue :sw 4, // `continue` can occur multiple times within a single switch prong. 2...4 => |v| { if (v > 3) { continue :sw 2; } else if (v == 3) { // `break` can target labeled loops. break :sw; } continue :sw 1; }, 1 => return, else => unreachable, } } ``` -------------------------------- ### Stack Trace Example Source: https://ziglang.org/documentation/0.16.0 Illustrates a traditional stack trace, which shows the call sequence leading to a panic but does not detail error handling logic or re-thrown errors. This is contrasted with Zig's error return traces. ```zig pub fn main() void { foo(12); } fn foo(x: i32) void { if (x >= 5) { bar(); } else { bang2(); } } fn bar() void { if (baz()) { quux(); } else { hello(); } } fn baz() bool { return bang1(); } fn quux() void { bang2(); } fn hello() void { bang2(); } fn bang1() bool { return false; } fn bang2() void { @panic("PermissionDenied"); } ``` ```shell $ `zig build-exe stack_trace.zig` $ `./stack_trace` thread 930211 panic: PermissionDenied /home/andy/src/zig/doc/langref/stack_trace.zig:38:5: 0x11d5e7a in bang2 (stack_trace.zig) @panic("PermissionDenied"); ^ /home/andy/src/zig/doc/langref/stack_trace.zig:30:10: 0x11d5efc in hello (stack_trace.zig) bang2(); ^ /home/andy/src/zig/doc/langref/stack_trace.zig:17:14: 0x11d5eb3 in bar (stack_trace.zig) hello(); ^ /home/andy/src/zig/doc/langref/stack_trace.zig:7:12: 0x11d5898 in foo (stack_trace.zig) bar(); ^ /home/andy/src/zig/doc/langref/stack_trace.zig:2:8: 0x11d5801 in main (stack_trace.zig) foo(12); ^ /home/andy/src/zig/lib/std/start.zig:685:59: 0x11d5121 in callMain (std.zig) if (fn_info.params.len == 0) return wrapMain(root.main()); ^ /home/andy/src/zig/lib/std/start.zig:190:5: 0x11d4b81 in _start (std.zig) asm volatile (switch (native_arch) { ^ (process terminated by signal) ``` -------------------------------- ### Compile Zig to WebAssembly for Node.js Source: https://ziglang.org/documentation/0.16.0 This example demonstrates compiling Zig code to WebAssembly for a freestanding environment, suitable for runtimes like Node.js. It requires an external JavaScript file to instantiate and run the WebAssembly module. ```zig extern fn print(i32) void; export fn add(a: i32, b: i32) void { print(a + b); } ``` ```shell $ zig build-exe math.zig -target wasm32-freestanding -fno-entry --export=add ``` ```javascript const fs = require('fs'); const source = fs.readFileSync("./math.wasm"); const typedArray = new Uint8Array(source); WebAssembly.instantiate(typedArray, { env: { print: (result) => { console.log(`The result is ${result}`); } }}).then(result => { const add = result.instance.exports.add; add(1, 2); }); ``` ```shell $ node test.js The result is 3 ``` -------------------------------- ### Function Reflection Example Source: https://ziglang.org/documentation/0.16.0 Demonstrates function reflection in Zig using `@typeInfo` to inspect parameter types and return types of functions like `testing.expect` and `testing.tmpDir`, and checking if a function is generic. ```zig const std = @import("std"); const math = std.math; const testing = std.testing; test "fn reflection" { try testing.expectEqual(bool, @typeInfo(@TypeOf(testing.expect)).@"fn".params[0].type.?); try testing.expectEqual(testing.TmpDir, @typeInfo(@TypeOf(testing.tmpDir)).@"fn".return_type.?); try testing.expect(@typeInfo(@TypeOf(math.Log2Int)).@"fn".is_generic); } ``` -------------------------------- ### Zig Print with Compile-Time Known Format String Source: https://ziglang.org/documentation/0.16.0 This example demonstrates the correct usage of the print function with a compile-time known format string and the appropriate number of arguments. Zig ensures that the format string and arguments are compatible during compilation. ```zig const print = @import("std").debug.print; const a_number: i32 = 1234; const a_string = "foobar"; const fmt = "here is a string: '{s}' here is a number: {}\\n"; pub fn main() void { print(fmt, .{ a_string, a_number }); } ``` ```shell $ `zig build-exe print_comptime-known_format.zig` $ `./print_comptime-known_format` here is a string: 'foobar' here is a number: 1234 ``` -------------------------------- ### Compile-time logging and error example Source: https://ziglang.org/documentation/0.16.0 This snippet demonstrates using @compileLog for debugging compile-time code and shows how such statements trigger a compile error. It also includes runtime output. ```zig const print = @import("std").debug.print; const num1 = blk: { var val1: i32 = 99; @compileLog("comptime val1 = ", val1); val1 = val1 + 1; break :blk val1; }; test "main" { @compileLog("comptime in main"); print("Runtime in main, num1 = {}.\n", .{num1}); } ``` -------------------------------- ### Zig allowzero Pointer Attribute Example Source: https://ziglang.org/documentation/0.16.0 Demonstrates the use of the `allowzero` attribute to allow a pointer to have address zero. This is useful on freestanding OS targets where address zero is mappable. Use Optional Pointers for null pointers. ```zig const std = @import("std"); const expectEqual = std.testing.expectEqual; test "allowzero" { var zero: usize = 0; // var to make to runtime-known _ = &zero; // suppress 'var is never mutated' error const ptr: *allowzero i32 = @ptrFromInt(zero); try expectEqual(0, @intFromPtr(ptr)); } ``` -------------------------------- ### Zig Switch Statement Example Source: https://ziglang.org/documentation/0.16.0 Illustrates the usage of the Zig switch statement with various features like combined cases, ranges, complex branches, and compile-time evaluated expressions. It also shows how to use switch outside functions. ```zig const std = @import("std"); const builtin = @import("builtin"); const expectEqual = std.testing.expectEqual; test "switch simple" { const a: u64 = 10; const zz: u64 = 103; // All branches of a switch expression must be able to be coerced to a // common type. // // Branches cannot fallthrough. If fallthrough behavior is desired, combine // the cases and use an if. const b = switch (a) { // Multiple cases can be combined via a "," 1, 2, 3 => 0, // Ranges can be specified using the ... syntax. These are inclusive // of both ends. 5...100 => 1, // Branches can be arbitrarily complex. 101 => blk: { const c: u64 = 5; break :blk c * 2 + 1; }, // Switching on arbitrary expressions is allowed as long as the // expression is known at compile-time. zz => zz, blk: { const d: u32 = 5; const e: u32 = 100; break :blk d + e; } => 107, // The else branch catches everything not already captured. // Else branches are mandatory unless the entire range of values // is handled. else => 9, }; try expectEqual(1, b); } // Switch expressions can be used outside a function: const os_msg = switch (builtin.target.os.tag) { .linux => "we found a linux user", else => "not a linux user", }; // Inside a function, switch statements implicitly are compile-time // evaluated if the target expression is compile-time known. test "switch inside function" { switch (builtin.target.os.tag) { .fuchsia => { // On an OS other than fuchsia, block is not even analyzed, // so this compile error is not triggered. // On fuchsia this compile error would be triggered. @compileError("fuchsia not supported"); }, else => {}, } } ``` -------------------------------- ### Zig Slice Array and Pointer Example Source: https://ziglang.org/documentation/0.16.0 Demonstrates slicing a pointer to an array and how the type of the resulting slice depends on whether the slice bounds are known at compile time. Shows how to modify elements through a mutable slice. ```zig var array: [10]u8 = undefined; const ptr = &array; try expectEqual(*[10]u8, @TypeOf(ptr)); // A pointer to an array can be sliced just like an array: var start: usize = 0; var end: usize = 5; _ = .{ &start, &end }; const slice = ptr[start..end]; // The slice is mutable because we sliced a mutable pointer. try expectEqual([]u8, @TypeOf(slice)); slice[2] = 3; try expectEqual(3, array[2]); // Again, slicing with comptime-known indexes will produce another pointer // to an array: const ptr2 = slice[2..3]; try expectEqual(1, ptr2.len); try expectEqual(3, ptr2[0]); try expectEqual(*[1]u8, @TypeOf(ptr2)); ``` -------------------------------- ### Zig Comptime Evaluation Example Source: https://ziglang.org/documentation/0.16.0 Demonstrates 'comptime' variables and 'inline' loops for partial compile-time evaluation. This Zig code defines functions and uses 'comptime' to conditionally apply them based on a compile-time prefix character. ```zig const expectEqual = @import("std").testing.expectEqual; const CmdFn = struct { name: []const u8, func: fn (i32) i32, }; const cmd_fns = [_]CmdFn{ CmdFn{ .name = "one", .func = one }, CmdFn{ .name = "two", .func = two }, CmdFn{ .name = "three", .func = three }, }; fn one(value: i32) i32 { return value + 1; } fn two(value: i32) i32 { return value + 2; } fn three(value: i32) i32 { return value + 3; } fn performFn(comptime prefix_char: u8, start_value: i32) i32 { var result: i32 = start_value; comptime var i = 0; inline while (i < cmd_fns.len) : (i += 1) { if (cmd_fns[i].name[0] == prefix_char) { result = cmd_fns[i].func(result); } } return result; } test "perform fn" { try expectEqual(6, performFn('t', 1)); try expectEqual(1, performFn('o', 0)); try expectEqual(99, performFn('w', 99)); } ``` -------------------------------- ### Multiline String Literal Example Source: https://ziglang.org/documentation/0.16.0 Demonstrates how to define a multiline string literal in Zig using the '\\' token to continue the string onto the next line and append a newline character. ```zig const hello_world_in_c = \#include \ \int main(int argc, char **argv) { \ printf("hello world\n"); \ return 0; \} ; ``` -------------------------------- ### Global Assembly Example Source: https://ziglang.org/documentation/0.16.0 This snippet shows how to embed global assembly code directly into a Zig program. It defines a function `my_func` using x86_64 assembly instructions. Ensure the target architecture and assembly syntax are correct for your system. ```zig const std = @import("std"); const expectEqual = std.testing.expectEqual; comptime { asm ( \.global my_func; \.type my_func, @function; \my_func: \ lea (%rdi,%rsi,1),%eax \ retq ); } extern fn my_func(a: i32, b: i32) i32; test "global assembly" { try expectEqual(46, my_func(12, 34)); } ``` -------------------------------- ### Using Inline Functions Source: https://ziglang.org/documentation/0.16.0 Illustrates the use of the `inline` keyword for functions, which forces semantic inlining and treats compile-time known arguments as Compile Time Parameters. This example shows a simple addition function. ```zig const std = @import("std"); pub fn main() void { if (foo(1200, 34) != 1234) { @compileError("bad"); } } inline fn foo(a: i32, b: i32) i32 { std.debug.print("runtime a = {} b = {}", .{ a, b }); return a + b; } ``` -------------------------------- ### Compile and Run Hello World Source: https://ziglang.org/documentation/0.16.0 Commands to compile a Zig source file into an executable and then run it. ```Shell $ `zig build-exe hello.zig` $ `./hello` ``` -------------------------------- ### Example of @call with a noinline function Source: https://ziglang.org/documentation/0.16.0 Demonstrates calling a function using the @call built-in with the 'auto' CallModifier. This example tests a function that is explicitly marked as noinline. ```zig const expectEqual = @import("std").testing.expectEqual; test "noinline function call" { try expectEqual(12, @call(.auto, add, .{ 3, 9 })); } fn add(a: i32, b: i32) i32 { return a + b; } ``` -------------------------------- ### Type Coercion Examples Source: https://ziglang.org/documentation/0.16.0 Demonstrates type coercion in Zig for variable declarations, function calls, and using the @as builtin. These examples show safe and unambiguous type conversions. ```zig test "type coercion - variable declaration" { const a: u8 = 1; const b: u16 = a; _ = b; } test "type coercion - function call" { const a: u8 = 1; foo(a); } fn foo(b: u16) void { _ = b; } test "type coercion - @as builtin" { const a: u8 = 1; const b = @as(u16, a); _ = b; } ``` -------------------------------- ### Custom max function for bool type Source: https://ziglang.org/documentation/0.16.0 Shows how to handle specific types within a `comptime` function by adding conditional logic. This example customizes the `max` function for `bool` types using a bitwise OR operation. ```zig fn max(comptime T: type, a: T, b: T) T { if (T == bool) { return a or b; } else if (a > b) { return a; } else { return b; } } test "try to compare bools" { try @import("std").testing.expectEqual(true, max(bool, false, true)); } ``` -------------------------------- ### Zig Sentinel-Terminated Pointer Example Source: https://ziglang.org/documentation/0.16.0 Shows how to use sentinel-terminated pointers (`[*:0]const u8`) for C-style null-terminated strings with `printf`. The example highlights a common error where a non-null-terminated slice is passed to a function expecting a sentinel. ```zig const std = @import("std"); // This is also available as `std.c.printf`. pub extern "c" fn printf(format: [*:0]const u8, ...) c_int; pub fn main() anyerror!void { _ = printf("Hello, world!\n"); // OK const msg = "Hello, world!\n"; const non_null_terminated_msg: [msg.len]u8 = msg.*; _ = printf(&non_null_terminated_msg); } ``` -------------------------------- ### Hello World with Inline Assembly on x86_64 Linux Source: https://ziglang.org/documentation/0.16.0 Implements a 'Hello, World!' program using inline assembly for system calls on x86_64 Linux. Requires building with `zig build-exe` and executing the binary. ```zig pub fn main() noreturn { const msg = "hello world\n"; _ = syscall3(SYS_write, STDOUT_FILENO, @intFromPtr(msg), msg.len); _ = syscall1(SYS_exit, 0); unreachable; } pub const SYS_write = 1; pub const SYS_exit = 60; pub const STDOUT_FILENO = 1; pub fn syscall1(number: usize, arg1: usize) usize { return asm volatile ("syscall" : [ret] "=={rax}" (-> usize), : [number] "{rax}" (number), [arg1] "{rdi}" (arg1), : .{ .rcx = true, .r11 = true }); } pub fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usize { return asm volatile ("syscall" : [ret] "=={rax}" (-> usize), : [number] "{rax}" (number), [arg1] "{rdi}" (arg1), [arg2] "{rsi}" (arg2), [arg3] "{rdx}" (arg3), : .{ .rcx = true, .r11 = true }); } ``` -------------------------------- ### Example of Program Panic Source: https://ziglang.org/documentation/0.16.0 This shell output shows the result of running the faulty Zig code, illustrating the panic that occurs due to the violated data invariant. It serves as a concrete example of the consequences of incorrect default field value usage. ```shell $ `zig build-exe bad_default_value.zig` $ `./bad_default_value` thread 932709 panic: reached unreachable code /home/andy/src/zig/lib/std/debug.zig:421:14: 0x1025eb9 in assert (std.zig) if (!ok) unreachable; // assertion failure ^ /home/andy/src/zig/doc/langref/bad_default_value.zig:8:15: 0x11d611a in categorize (bad_default_value.zig) assert(t.maximum >= t.minimum); ^ /home/andy/src/zig/doc/langref/bad_default_value.zig:19:42: 0x11d4bce in main (bad_default_value.zig) const category = threshold.categorize(0.90); ^ /home/andy/src/zig/lib/std/start.zig:685:59: 0x11d51ac in callMain (std.zig) if (fn_info.params.len == 0) return wrapMain(root.main()); ^ /home/andy/src/zig/lib/std/start.zig:190:5: 0x11d4b81 in _start (std.zig) asm volatile (switch (native_arch) { ^ (process terminated by signal) ``` -------------------------------- ### Get Type of Expression Source: https://ziglang.org/documentation/0.16.0 Returns the type of an expression. Expressions are evaluated but guaranteed to have no runtime side-effects. ```zig @TypeOf(...) type ``` -------------------------------- ### @cVaStart Source: https://ziglang.org/documentation/0.16.0 Implements the C macro `va_start`. It initializes a variadic argument list. ```APIDOC ## @cVaStart ### Description Implements the C macro `va_start`. This function initializes a `VaList` for use within a variadic function. ### Signature ```zig @cVaStart() std.builtin.VaList ``` ### Notes Only valid inside a variadic function. ### See Also * @cVaArg * @cVaCopy * @cVaEnd ``` -------------------------------- ### Compiling and Running a Zig Program Source: https://ziglang.org/documentation/0.16.0 Demonstrates the shell commands to compile a Zig executable and then run it. ```shell $ `zig build-exe entry_point.zig` $ `./entry_point` Hello, World! ``` -------------------------------- ### Get Work Group Size Source: https://ziglang.org/documentation/0.16.0 Returns the number of work items in a work group for a given dimension. ```zig @workGroupSize(comptime dimension: u32) u32 ``` -------------------------------- ### Compile and Run Formatted Hello World Source: https://ziglang.org/documentation/0.16.0 Commands to compile and execute the simplified 'Hello, World!' program. ```Shell $ `zig build-exe hello_again.zig` $ `./hello_again` ``` -------------------------------- ### Get Work Group ID Source: https://ziglang.org/documentation/0.16.0 Returns the index of the work group in the current kernel invocation for a given dimension. ```zig @workGroupId(comptime dimension: u32) u32 ``` -------------------------------- ### Formatted Hello World with Debug Print Source: https://ziglang.org/documentation/0.16.0 A simplified 'Hello, World!' using `std.debug.print` for formatted output. This version omits error handling for simplicity. ```Zig const std = @import("std"); pub fn main() void { std.debug.print("Hello, {s}!\n", .{"World"}); } ``` -------------------------------- ### Noreturn Type Example Source: https://ziglang.org/documentation/0.16.0 Demonstrates how the `noreturn` type is compatible with other types in conditional expressions. The `return` keyword can be used as an expression. ```zig fn foo(condition: bool, b: u32) void { const a = if (condition) b else return; _ = a; @panic("do something with a"); } test "noreturn" { foo(false, 1); } ``` -------------------------------- ### Thread Local Variables Source: https://ziglang.org/documentation/0.16.0 Demonstrates thread-local variables using the `threadlocal` keyword. Each thread gets a separate instance of the variable. ```zig const std = @import("std"); const assert = std.debug.assert; threadlocal var x: i32 = 1234; test "thread local storage" { const thread1 = try std.Thread.spawn(.{}, testTls, .{}); const thread2 = try std.Thread.spawn(.{}, testTls, .{}); testTls(); thread1.join(); thread2.join(); } fn testTls() void { assert(x == 1234); x += 1; assert(x == 1235); } ``` -------------------------------- ### @branchHint Source: https://ziglang.org/documentation/0.16.0 Provides a hint to the optimizer about the likelihood of a control flow branch being taken. This can improve performance by guiding branch prediction. ```APIDOC ## @branchHint ### Description Hints to the optimizer how likely a given branch of control flow is to be reached. `BranchHint` can be found with `@import("std").builtin.BranchHint`. This function is only valid as the first statement in a control flow branch, or the first statement in a function. ### Signature ```zig @branchHint(hint: BranchHint) void ``` ```