### Shell Commands for Zig Values Example Source: https://ziglang.org/documentation/master Provides the shell commands to compile and run the `values.zig` example, along with the expected output. ```shell $ `zig build-exe values.zig` $ `./values` 1 + 1 = 2 7.0 / 3.0 = 2.3333333 false true false optional 1 type: ?[]const u8 value: null optional 2 type: ?[]const u8 value: hi error union 1 type: error{ExampleErrorVariant}!i32 value: error.ExampleErrorVariant error union 2 type: error{ExampleErrorVariant}!i32 value: 1234 ``` -------------------------------- ### Global Assembly Example Source: https://ziglang.org/documentation/master Demonstrates global assembly usage in Zig, which is unconditionally included and has no inputs, outputs, or clobbers. This example defines a simple function 'my_func' using x86-64 assembly. ```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)); } ``` ```shell $ `zig test test_global_assembly.zig -target x86_64-linux -fllvm` 1/1 test_global_assembly.test.global assembly...OK All 1 tests passed. ``` -------------------------------- ### Build and Run Type Name Example Source: https://ziglang.org/documentation/master Commands to compile and execute the Zig program that prints a type's fully-qualified name. ```shell $ `zig build-exe redundant_fqn.zig` $ `./redundant_fqn` ``` -------------------------------- ### Global Assembly Example Source: https://ziglang.org/documentation/master Demonstrates the usage of global assembly in Zig, showing how to define assembly code at the namespace level. ```APIDOC ## Global Assembly When an assembly expression occurs in a Namespace level comptime block, this is **global assembly**. This kind of assembly has different rules than inline assembly. First, `volatile` is not valid because all global assembly is unconditionally included. Second, there are no inputs, outputs, or clobbers. All global assembly is concatenated verbatim into one long string and assembled together. There are no template substitution rules regarding `%` as there are in inline assembly expressions. ### Example ```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)); } ``` ### Test Output ```shell $ `zig test test_global_assembly.zig -target x86_64-linux -fllvm` 1/1 test_global_assembly.test.global assembly...OK All 1 tests passed. ``` ``` -------------------------------- ### Zig Comments Example Source: https://ziglang.org/documentation/master Demonstrates the use of single-line comments (`//`) in Zig. This example shows both full-line comments and inline comments, as well as a commented-out line of code. ```zig const print = @import("std").debug.print; pub fn main() void { // Comments in Zig start with "//" and end at the next LF byte (end of line). // The line below is a comment and won't be executed. //print("Hello?", .{}); print("Hello, world!\n", .{}); // another comment } ``` ```shell $ `zig build-exe comments.zig` $ `./comments` Hello, world! ``` -------------------------------- ### Zig Values and Types Example Source: https://ziglang.org/documentation/master Shows basic Zig value types including integers, floats, booleans, optionals, and error unions. This example also demonstrates basic arithmetic, logical operations, and how to print values to the console. ```zig // Top-level declarations are order-independent: const print = std.debug.print; const std = @import("std"); const os = std.os; const assert = std.debug.assert; // Custom error set definition: const ExampleErrorSet = error{ ExampleErrorVariant, }; pub fn main() void { // integers const one_plus_one: i32 = 1 + 1; print("1 + 1 = {} ", .{one_plus_one}); // floats const seven_div_three: f32 = 7.0 / 3.0; print("7.0 / 3.0 = {} ", .{seven_div_three}); // boolean print("{} {} {} ", .{ true and false, true or false, !true, }); // optional var optional_value: ?[]const u8 = null; assert(optional_value == null); print("\noptional 1\ntype: {} value: {{?s}} ", .{ @TypeOf(optional_value), optional_value, }); optional_value = "hi"; assert(optional_value != null); print("\noptional 2\ntype: {} value: {{?s}} ", .{ @TypeOf(optional_value), optional_value, }); // error union var number_or_error: ExampleErrorSet!i32 = ExampleErrorSet.ExampleErrorVariant; print("\nerror union 1\ntype: {} value: {{!}} ", .{ @TypeOf(number_or_error), number_or_error, }); number_or_error = 1234; print("\nerror union 2\ntype: {} value: {{!}} ", .{ @TypeOf(number_or_error), number_or_error, }); } ``` -------------------------------- ### Run WASI Executable with Arguments Source: https://ziglang.org/documentation/master Example of running a compiled WASI executable with command-line arguments using wasmtime. ```shell `wasmtime wasi_args.wasm 123 hello` ``` -------------------------------- ### Multiline String Literal Example Source: https://ziglang.org/documentation/master Demonstrates creating a multiline string literal in Zig using the '\\' token. Newlines are not included unless the next line also starts with '\\'. ```zig const hello_world_in_c = \#include \ \int main(int argc, char **argv) { \ printf("hello world\n"); \ return 0; \} ; ``` -------------------------------- ### Zig Doc Comments Example Source: https://ziglang.org/documentation/master Illustrates the use of documentation comments (`///`) in Zig for generating package documentation. This example defines a `Timestamp` struct with documented fields and a documented function. ```zig /// A structure for storing a timestamp, with nanosecond precision (this is a /// multiline doc comment). const Timestamp = struct { /// The number of seconds since the epoch (this is also a doc comment). seconds: i64, // signed so we can represent pre-1970 (not a doc comment) /// The number of nanoseconds past the second (doc comment again). nanos: u32, /// Returns a `Timestamp` struct representing the Unix epoch; that is, the /// moment of 1970 Jan 1 00:00:00 UTC (this is a doc comment too). pub fn unixEpoch() Timestamp { return Timestamp{ .seconds = 0, .nanos = 0, }; } }; ``` -------------------------------- ### Create a 0-Terminated Slice using Slicing Syntax Source: https://ziglang.org/documentation/master Shows how to create a sentinel-terminated slice from an array using the `data[start..end :x]` syntax. This example creates a slice with a runtime-determined length and a specified sentinel value. ```zig const std = @import("std"); const expectEqual = std.testing.expectEqual; test "0-terminated slicing" { var array = [_]u8{ 3, 2, 1, 0, 3, 2, 1, 0 }; var runtime_length: usize = 3; _ = &runtime_length; const slice = array[0..runtime_length :0]; try expectEqual([:0]u8, @TypeOf(slice)); try expectEqual(3, slice.len); } ``` -------------------------------- ### Run WASI Executable with Preopens Source: https://ziglang.org/documentation/master Example of running a compiled WASI executable with preopened directories using wasmtime. The `--dir .` flag makes the current directory available. ```shell `wasmtime --dir=. wasi_preopens.wasm` ``` -------------------------------- ### Zig Test Execution for Arrays Source: https://ziglang.org/documentation/master This shows the shell command to compile and run the tests defined in the Zig array example files. ```shell $ `zig test test_arrays.zig` 1/4 test_arrays.test.iterate over an array...OK 2/4 test_arrays.test.modify an array...OK 3/4 test_arrays.test.compile-time array initialization...OK 4/4 test_arrays.test.array initialization with function calls...OK All 4 tests passed. ``` ```shell $ `zig test test_multidimensional_arrays.zig` 1/1 test_multidimensional_arrays.test.multidimensional arrays...OK All 1 tests passed. ``` -------------------------------- ### Zig Test Inline For Loop Execution Source: https://ziglang.org/documentation/master Shows the output of testing the Zig code example for inline for loops, confirming that the test passes. ```shell $ `zig test test_inline_for.zig` 1/1 test_inline_for.test.inline for loop...OK All 1 tests passed. ``` -------------------------------- ### Zig Function Reflection Example Source: https://ziglang.org/documentation/master Shows how to use `@typeInfo` to inspect function metadata, such as parameter types and return types, and check 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 Test For Loop Execution Source: https://ziglang.org/documentation/master Shows the output of testing the Zig code examples for for loops, confirming that all tests pass. ```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. ``` -------------------------------- ### Zig Stack Trace Example Source: https://ziglang.org/documentation/master Illustrates a traditional stack trace, which shows the call sequence leading to a panic but does not detail error propagation when errors are returned and potentially replaced. ```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 904967 panic: PermissionDenied /home/ci/work/zig-bootstrap/zig/doc/langref/stack_trace.zig:38:5: 0x11d970a in bang2 (stack_trace.zig) @panic("PermissionDenied"); ^ /home/ci/work/zig-bootstrap/zig/doc/langref/stack_trace.zig:30:10: 0x11d978c in hello (stack_trace.zig) bang2(); ^ /home/ci/work/zig-bootstrap/zig/doc/langref/stack_trace.zig:17:14: 0x11d9743 in bar (stack_trace.zig) hello(); ^ /home/ci/work/zig-bootstrap/zig/doc/langref/stack_trace.zig:7:12: 0x11d9128 in foo (stack_trace.zig) bar(); ^ /home/ci/work/zig-bootstrap/zig/doc/langref/stack_trace.zig:2:8: 0x11d9091 in main (stack_trace.zig) foo(12); ^ /home/ci/work/zig-bootstrap/out/host/lib/zig/std/start.zig:699:59: 0x11d89a1 in callMain (std.zig) if (fn_info.params.len == 0) return wrapMain(root.main()); ^ /home/ci/work/zig-bootstrap/out/host/lib/zig/std/start.zig:191:5: 0x11d83d1 in _start (std.zig) asm volatile (switch (native_arch) { ^ (process terminated by signal) ``` -------------------------------- ### Zig Switch Statement Examples Source: https://ziglang.org/documentation/master Illustrates the versatility of Zig's switch statement, including handling ranges, complex branches, and compile-time evaluation based on target OS. Branches cannot fall through. ```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 => {}, } } ``` -------------------------------- ### Catching Overflow with Standard Library Math Functions Source: https://ziglang.org/documentation/master This example demonstrates how to use standard library math functions like `std.math.add` which return errors on overflow. This allows for graceful error handling instead of a panic. ```zig const math = @import("std").math; const print = @import("std").debug.print; pub fn main() !void { var byte: u8 = 255; byte = if (math.add(u8, byte, 1)) |result| result else |err| { print("unable to add one: {s}\n", .{@errorName(err)}); return err; }; print("result: {}\n", .{byte}); } ``` ```shell $ `zig build-exe math_add.zig` $ `./math_add` unable to add one: Overflow error: Overflow /home/ci/work/zig-bootstrap/out/host/lib/zig/std/math.zig:565:21: 0x113ea24 in add__anon_22740 (std.zig) if (ov[1] != 0) return error.Overflow; ^ /home/ci/work/zig-bootstrap/zig/doc/langref/math_add.zig:8:9: 0x11d848f in main (math_add.zig) return err; ^ ``` -------------------------------- ### Zig Test Labeled For Loop Execution Source: https://ziglang.org/documentation/master Shows the output of testing the Zig code examples for labeled for loops, confirming that all tests pass. ```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. ``` -------------------------------- ### Basic Print Usage in Zig Source: https://ziglang.org/documentation/master Demonstrates the basic usage of the `std.debug.print` function to output formatted strings and numbers. Ensure the Zig compiler is installed and the file is compiled using `zig build-exe`. ```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: {} ", .{ a_string, a_number }); } ``` ```shell $ `zig build-exe print.zig` $ `./print` here is a string: 'foobar' here is a number: 1234 ``` -------------------------------- ### Runtime Integer Overflow Handling Source: https://ziglang.org/documentation/master This example shows how integer overflow is handled at runtime. By default, Zig will panic on overflow, providing a stack trace and error message. ```zig const std = @import("std"); pub fn main() void { var byte: u8 = 255; byte += 1; std.debug.print("value: {}\n", .{byte}); } ``` ```shell $ `zig build-exe runtime_overflow.zig` $ `./runtime_overflow` thread 904672 panic: integer overflow /home/ci/work/zig-bootstrap/zig/doc/langref/runtime_overflow.zig:5:10: 0x11d90b5 in main (runtime_overflow.zig) byte += 1; ^ /home/ci/work/zig-bootstrap/out/host/lib/zig/std/start.zig:699:59: 0x11d89a1 in callMain (std.zig) if (fn_info.params.len == 0) return wrapMain(root.main()); ^ /home/ci/work/zig-bootstrap/out/host/lib/zig/std/start.zig:191:5: 0x11d83d1 in _start (std.zig) asm volatile (switch (native_arch) { ^ (process terminated by signal) ``` -------------------------------- ### Zig Switch Continue Example Source: https://ziglang.org/documentation/master Demonstrates using 'continue :sw' to jump to a specific prong within a labeled switch statement. 'break :sw' can also be used to exit the labeled 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, } } ``` -------------------------------- ### Zig Build System for C Library and Executable Source: https://ziglang.org/documentation/master Configure the Zig Build System to create a dynamic library from a Zig file and link it with a C executable. This example also includes running the executable as a build step. ```zig const std = @import("std"); pub fn build(b: *std.Build) void { const lib = b.addLibrary(.{ .linkage = .dynamic, .name = "mathtest", .root_module = b.createModule(.{ .root_source_file = b.path("mathtest.zig"), }), .version = .{ .major = 1, .minor = 0, .patch = 0 }, }); const exe = b.addExecutable(.{ .name = "test", .root_module = b.createModule(.{ .link_libc = true, }), }); exe.root_module.addCSourceFile(.{ .file = b.path("test.c"), .flags = &.{" -std=c99"} }); exe.root_module.linkLibrary(lib); b.default_step.dependOn(&exe.step); const run_cmd = exe.run(); const test_step = b.step("test", "Test the program"); test_step.dependOn(&run_cmd.step); } ``` -------------------------------- ### Get Source Location with @src Source: https://ziglang.org/documentation/master Retrieves a SourceLocation struct containing the function's name and its position in the source code. This must be called within a function. The example demonstrates asserting the line, column, function name, and file. ```zig const std = @import("std"); const expect = std.testing.expect; const expectEqual = std.testing.expectEqual; test "@src" { try doTheTest(); } fn doTheTest() !void { const src = @src(); try expectEqual(10, src.line); try expectEqual(17, src.column); try expect(std.mem.endsWith(u8, src.fn_name, "doTheTest")); try expect(std.mem.endsWith(u8, src.file, "test_src_builtin.zig")); } ``` -------------------------------- ### Hello World with Inline Assembly (x86_64 Linux) Source: https://ziglang.org/documentation/master Implements a 'Hello, World!' program using inline assembly to make direct system calls for writing to stdout and exiting. Ensure you compile with the correct target for your system. ```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 }); } ``` ```shell $ `zig build-exe inline_assembly.zig -target x86_64-linux` $ `./inline_assembly` hello world ``` -------------------------------- ### Zig Slice Pointer Example Source: https://ziglang.org/documentation/master Demonstrates slicing a pointer to an array. Slicing a mutable pointer results in a mutable slice. Slicing with comptime-known indexes produces another pointer to an array. ```zig test "slice pointer" { 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 Basic Slices Example Source: https://ziglang.org/documentation/master Demonstrates the creation and manipulation of basic slices in Zig, including comparisons with arrays, type checking, and handling of empty slices. It also shows how slicing with comptime-known positions results in an array pointer. ```zig const expectEqual = @import("std").testing.expectEqual; const expectEqualSlices = @import("std").testing.expectEqualSlices; test "basic slices" { var array = [_]i32{ 1, 2, 3, 4 }; var known_at_runtime_zero: usize = 0; _ = &known_at_runtime_zero; const slice = array[known_at_runtime_zero..array.len]; // alternative initialization using result location const alt_slice: []const i32 = &.{ 1, 2, 3, 4 }; try expectEqualSlices(i32, slice, alt_slice); try expectEqual([]i32, @TypeOf(slice)); try expectEqual(&array[0], &slice[0]); try expectEqual(array.len, slice.len); // If you slice with comptime-known start and end positions, the result is // a pointer to an array, rather than a slice. const array_ptr = array[0..array.len]; try expectEqual(*[array.len]i32, @TypeOf(array_ptr)); // You can perform a slice-by-length by slicing twice. This allows the compiler // to perform some optimisations like recognising a comptime-known length when // the start position is only known at runtime. var runtime_start: usize = 1; _ = &runtime_start; const length = 2; const array_ptr_len = array[runtime_start..][0..length]; try expectEqual(*[length]i32, @TypeOf(array_ptr_len)); // Using the address-of operator on a slice gives a single-item pointer. try expectEqual(*i32, @TypeOf(&slice[0])); // Using the `ptr` field gives a many-item pointer. try expectEqual([*]i32, @TypeOf(slice.ptr)); try expectEqual(@intFromPtr(slice.ptr), @intFromPtr(&slice[0])); // Slices have array bounds checking. If you try to access something out // of bounds, you'll get a safety check failure: slice[10] += 1; // Note that `slice.ptr` does not invoke safety checking, while `&slice[0]` // asserts that the slice has len > 0. // Empty slices can be created like this: const empty1 = &[0]u8{}; // If the type is known you can use this short hand: const empty2: []u8 = &.{}; try expectEqual(0, empty1.len); try expectEqual(0, empty2.len); // A zero-length initialization can always be used to create an empty slice, even if the slice is mutable. // This is because the pointed-to data is zero bits long, so its immutability is irrelevant. } ``` -------------------------------- ### Run Zig Standard Library Documentation Source: https://ziglang.org/documentation/master Use this command to render the Zig Standard Library documentation locally. ```shell zig std ``` -------------------------------- ### Zig Slice Bounds Checking Failure Example Source: https://ziglang.org/documentation/master Illustrates a runtime bounds checking failure in Zig when accessing a slice out of its bounds. This example is intended to be run and will cause a panic. ```shell $ `zig test test_basic_slices.zig` 1/1 test_basic_slices.test.basic slices...thread 905995 panic: index out of bounds: index 10, len 4 /home/ci/work/zig-bootstrap/zig/doc/langref/test_basic_slices.zig:41:10: 0x123ac18 in test.basic slices (test_basic_slices.zig) slice[10] += 1; ^ /home/ci/work/zig-bootstrap/out/host/lib/zig/compiler/test_runner.zig:291:25: 0x11f3f26 in mainTerminal (test_runner.zig) if (test_fn.func()) |_| { ^ /home/ci/work/zig-bootstrap/out/host/lib/zig/compiler/test_runner.zig:73:28: 0x11f3742 in main (test_runner.zig) return mainTerminal(init); ^ /home/ci/work/zig-bootstrap/out/host/lib/zig/std/start.zig:700:88: 0x11eff55 in callMain (std.zig) if (fn_info.params[0].type.? == std.process.Init.Minimal) return wrapMain(root.main(.{ ^ /home/ci/work/zig-bootstrap/out/host/lib/zig/std/start.zig:191:5: 0x11ef931 in _start (std.zig) asm volatile (switch (native_arch) { ^ error: the following test command terminated with signal ABRT: /home/ci/work/zig-bootstrap/out/zig-local-cache/o/a3808d2c3b392a2886ddd366fade6274/test --seed=0xaca0e66c ``` -------------------------------- ### Build and Run Mixed Object Files Source: https://ziglang.org/documentation/master Build the project using the Zig Build System and then run the resulting executable. This verifies that the Zig object file was correctly linked with the C code. ```shell $ `zig build` $ `./zig-out/bin/test` all your base are belong to us ``` -------------------------------- ### Compile-time Branch Limit Exceeded Example Source: https://ziglang.org/documentation/master This example demonstrates a compile-time error when the number of backwards branches in a comptime loop exceeds the default limit of 1000. It shows the error message and the note suggesting the use of @setEvalBranchQuota. ```zig test "foo" { comptime { var i = 0; while (i < 1001) : (i += 1) {} } } ``` ```shell $ `zig test test_without_setEvalBranchQuota_builtin.zig` /home/ci/work/zig-bootstrap/zig/doc/langref/test_without_setEvalBranchQuota_builtin.zig:4:9: error: evaluation exceeded 1000 backwards branches while (i < 1001) : (i += 1) {} ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/ci/work/zig-bootstrap/zig/doc/langref/test_without_setEvalBranchQuota_builtin.zig:4:9: note: use @setEvalBranchQuota() to raise the branch limit from 1000 ``` -------------------------------- ### Example of "builtin" Package Contents Source: https://ziglang.org/documentation/master This snippet illustrates the various compile-time constants available through the "builtin" package, including Zig version, target details, build configurations, and optimization modes. Use feature detection over version checks when supporting multiple Zig versions. ```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.17.0-dev.224+c166c49b1"; 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.znver2, .features = std.Target.x86.featureSet(&.{ ."64bit", .adx, .aes, .allow_light_256_bit, .avx, .avx2, .bmi, .bmi2, .branchfusion, .clflushopt, .clwb, .clzero, .cmov, .crc32, .cx16, .cx8, .f16c, .fast_15bytenop, .fast_bextr, .fast_imm16, .fast_lzcnt, .fast_movbe, .fast_scalar_fsqrt, .fast_scalar_shift_masks, .fast_variable_perlane_shuffle, .fast_vector_fsqrt, .fma, .fsgsbase, .fxsr, .idivq_to_divl, .lzcnt, .mmx, .movbe, .mwaitx, .nopl, .pclmul, .popcnt, .prfchw, .rdpid, .rdpru, .rdrnd, .rdseed, .sahf, .sbb_dep_breaking, .sha, .slow_shld, .smap, .smep, .sse, .sse2, .sse3, .sse4_1, .sse4_2, .sse4a, .ssse3, .vzeroupper, .wbnoinvd, .x87, .xsave, .xsavec, .xsaveopt, .xsaves, }), }; pub const os: std.Target.Os = .{ .tag = .linux, .version_range = .{.linux = .{ .range = .{ .min = .{ .major = 5, .minor = 10, .patch = 0, }, .max = .{ .major = 5, .minor = 10, .patch = 0, }, }, .glibc = .{ .major = 2, .minor = 31, .patch = 0, }, .android = 29, }}, }; pub const target: std.Target = .{ .cpu = cpu, .os = os, .abi = abi, .ofmt = object_format, .dynamic_linker = .init("/lib64/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; ``` -------------------------------- ### Zig Hello World Program Source: https://ziglang.org/documentation/master A basic Zig program that prints "Hello, World!" to standard output using streaming writes. This example demonstrates basic I/O operations and error handling with `try`. ```zig const std = @import("std"); pub fn main(init: std.process.Init) !void { try std.io.File.stdout().writeStreamingAll(init.io, "Hello, World!\n"); } ``` ```shell $ `zig build-exe hello.zig` $ `./hello` Hello, World! ``` -------------------------------- ### Get Function Return Address with @returnAddress Source: https://ziglang.org/documentation/master Use @returnAddress to get the address of the next instruction to be executed upon function return. This function is only valid within function scope and its implications are target-specific. If the function is inlined, the returned address applies to the calling function. ```zig @returnAddress() usize ``` -------------------------------- ### Zig Naming and Import Conventions Source: https://ziglang.org/documentation/master Demonstrates Zig's naming conventions for namespaces, types, and variables, along with how to import modules. It also shows how to handle acronyms and special characters in identifiers. ```zig const namespace_name = @import("dir_name/file_name.zig"); const TypeName = @import("dir_name/TypeName.zig"); var global_var: i32 = undefined; const const_name = 42; const PrimitiveTypeAlias = f32; const StructName = struct { field: i32, }; const StructAlias = StructName; fn functionName(param_name: TypeName) void { var functionPointer = functionName; functionPointer(); functionPointer = otherFunction; functionPointer(); } const functionAlias = functionName; fn ListTemplateFunction(comptime ChildType: type, comptime fixed_size: usize) type { return List(ChildType, fixed_size); } fn ShortList(comptime T: type, comptime n: usize) type { return struct { field_name: [n]T, fn methodName() void {} }; } // The word XML loses its casing when used in Zig identifiers. const xml_document = \ \ \ ; const XmlParser = struct { field: i32, }; // The initials BE (Big Endian) are just another word in Zig identifier names. fn readU32Be() u32 {} ``` -------------------------------- ### Get Work Group Size with @workGroupSize Source: https://ziglang.org/documentation/master Returns the number of work items in a work group for a specified dimension. ```zig @workGroupSize(comptime dimension: u32) u32 ``` -------------------------------- ### Build Static C Library with Zig Source: https://ziglang.org/documentation/master Compile a Zig file into a static C library using the `zig build-lib` command. ```shell `zig build-lib mathtest.zig` ``` -------------------------------- ### Get Type Name with @typeName Source: https://ziglang.org/documentation/master Returns the fully qualified string representation of a type, including its parent namespace. ```zig @typeName(T: type) *const [N:0]u8 ``` -------------------------------- ### Build WASI Executable for Preopens Source: https://ziglang.org/documentation/master Command to compile a Zig file into a WASM32 WASI executable for demonstrating preopens. ```shell `zig build-exe wasi_preopens.zig -target wasm32-wasi` ``` -------------------------------- ### Handle Errors with Catch Source: https://ziglang.org/documentation/master Demonstrates how to use the `catch` keyword to provide a default value when an error occurs. ```zig const value: anyerror!u32 = error.Broken; const unwrapped = value catch 1234; unwrapped == 1234 ``` -------------------------------- ### Get Work Group ID with @workGroupId Source: https://ziglang.org/documentation/master Returns the index of the work group in the current kernel invocation for a specified dimension. ```zig @workGroupId(comptime dimension: u32) u32 ``` -------------------------------- ### Zig Build System for Mixing Object Files Source: https://ziglang.org/documentation/master Configure the Zig Build System to create an object file from a Zig source and link it with a C source file to produce an executable. This demonstrates mixing Zig and C object files. ```zig const std = @import("std"); pub fn build(b: *std.Build) void { const obj = b.addObject(.{ .name = "base64", .root_module = b.createModule(.{ .root_source_file = b.path("base64.zig"), }), }); const exe = b.addExecutable(.{ .name = "test", .root_module = b.createModule(.{ .link_libc = true, }), }); exe.root_module.addCSourceFile(.{ .file = b.path("test.c"), .flags = &.{" -std=c99"} }); exe.root_module.addObject(obj); b.installArtifact(exe); } ``` -------------------------------- ### Run Zig Build with Test Step Source: https://ziglang.org/documentation/master Execute the Zig build process, which includes compiling the C executable and running it as defined in the build script. ```shell `zig build test` ``` -------------------------------- ### Get Type of Expression with @TypeOf Source: https://ziglang.org/documentation/master Returns the type of an expression. Expressions passed to @TypeOf are evaluated but guaranteed to have no runtime side-effects. ```zig @TypeOf(...) type ``` ```zig const std = @import("std"); const expectEqual = std.testing.expectEqual; test "no runtime side effects" { var data: i32 = 0; const T = @TypeOf(foo(i32, &data)); try expectEqual(i32, T); try expectEqual(0, data); } fn foo(comptime T: type, ptr: *T) T { ptr.* += 1; return ptr.*; } ``` -------------------------------- ### Compiling and Running Zig Program Source: https://ziglang.org/documentation/master Commands to compile a Zig executable and run it from the shell. The output demonstrates the 'Hello, World!' message. ```shell $ `zig build-exe entry_point.zig` $ `./entry_point` Hello, World! ``` -------------------------------- ### Zig Test Unreachable Code Source: https://ziglang.org/documentation/master This example demonstrates an error scenario where a compile-time assertion fails, leading to unreachable code being detected during testing. ```shell Shell``` $ `zig test test_fibonacci_comptime_unreachable.zig` /home/ci/work/zig-bootstrap/out/lib/zig/std/debug.zig:420:14: error: reached unreachable code if (!ok) unreachable; // assertion failure ^~~~~~~~~~~ /home/ci/work/zig-bootstrap/zig/doc/langref/test_fibonacci_comptime_unreachable.zig:9:24: note: called at comptime here try comptime assert(fibonacci(7) == 99999); ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~ ``` ``` -------------------------------- ### Zig Hello World with Formatted Printing Source: https://ziglang.org/documentation/master A simplified Zig program for printing "Hello, World!" using `std.debug.print`. This method is often preferred for its simplicity and formatted output capabilities, and it omits explicit error handling for the print operation. ```zig const std = @import("std"); pub fn main() void { std.debug.print("Hello, {s}!\n", .{"World"}); } ``` ```shell $ `zig build-exe hello_again.zig` $ `./hello_again` Hello, World! ``` -------------------------------- ### Defer execution order in Zig Source: https://ziglang.org/documentation/master Illustrates that defer statements are executed in reverse order of their appearance. This example shows how nested defers are unwound. ```zig const std = @import("std"); const print = std.debug.print; pub fn main() void { print("\n", .{}); defer { print("1 ", .{}); } defer { print("2 ", .{}); } if (false) { // defers are not run if they are never executed. defer { print("3 ", .{}); } } } ``` -------------------------------- ### Zig Program Entry Point with std.start Source: https://ziglang.org/documentation/master Defines the standard `main` function as the program's entry point, which is called by `std.start` after initialization. This function can return `void` or `u8` for exit codes, or an error. If `_start` is uncommented, it suppresses `std.start` logic. ```zig /// `std.start` imports this file using `@import("root")`, and uses this declaration as the program's /// user-provided entry point. It can return any of the following types: /// * `void` /// * `E!void`, for any error set `E` /// * `u8` /// * `E!u8`, for any error set `E` /// Returning a `void` value from this function will exit with code 0. /// Returning a `u8` value from this function will exit with the given status code. /// Returning an error value from this function will print an Error Return Trace and exit with code 1. pub fn main() void { std.debug.print("Hello, World!\n", .{}); } // If uncommented, this declaration would suppress the usual std.start logic, causing // the `main` declaration above to be ignored. //pub const _start = {}; const std = @import("std"); ``` -------------------------------- ### Get Error Name - @errorName Source: https://ziglang.org/documentation/master Returns the string representation of an error. No error name table is generated if calls are compile-time known or absent. ```zig @errorName(err: anyerror) [:0]const u8 ``` -------------------------------- ### Compiling and Running Zig Program with libc Source: https://ziglang.org/documentation/master Commands to compile a Zig executable with libc linkage and run it. The output shows the program's greeting and its first argument. ```shell $ `zig build-exe libc_export_entry_point.zig -lc` $ `./libc_export_entry_point` Hello! argv[0] is './libc_export_entry_point' ``` -------------------------------- ### Get Byte Offset of Struct Field in Zig Source: https://ziglang.org/documentation/master Returns the byte offset of a specified `field_name` within a struct `T` relative to its containing struct. ```zig @offsetOf(comptime T: type, comptime field_name: []const u8) comptime_int ``` -------------------------------- ### Declare and Use Optional Pointer Source: https://ziglang.org/documentation/master Illustrates declaring an optional pointer, assigning it a memory address, dereferencing it safely, and verifying its size against a non-optional pointer. ```zig const expectEqual = @import("std").testing.expectEqual; test "optional pointers" { // Pointers cannot be null. If you want a null pointer, use the optional // prefix `?` to make the pointer type optional. var ptr: ?*i32 = null; var x: i32 = 1; ptr = &x; try expectEqual(1, ptr.?.*); // Optional pointers are the same size as normal pointers, because pointer // value 0 is used as the null value. try expectEqual(@sizeOf(?*i32), @sizeOf(*i32)); } ```