Builtin Functions

    Performs result.* = a + b. If overflow or underflow occurs, stores the overflowed bits in result and returns true. If no overflow or underflow occurs, returns false.

    @alignCast

    1. @alignCast(comptime alignment: u29, ptr: var) var

    ptr can be *T, fn(), ?*T, ?fn(), or []T. It returns the same type as ptr except with the alignment adjusted to the new value.

    A is added to the generated code to make sure the pointer is aligned as promised.

    @alignOf

    1. @alignOf(comptime T: type) comptime_int

    This function returns the number of bytes that this type should be aligned to for the current target to match the C ABI. When the child type of a pointer has this alignment, the alignment can be omitted from the type.

    1. const assert = @import("std").debug.assert;
    2. comptime {
    3. assert(*u32 == *align(@alignOf(u32)) u32);
    4. }

    The result is a target-specific compile time constant. It is guaranteed to be less than or equal to @sizeOf(T).

    See also:

    @ArgType

    1. @ArgType(comptime T: type, comptime n: usize) type

    This builtin function takes a function type and returns the type of the parameter at index n.

    T must be a function type.

    Note: This function is deprecated. Use @typeInfo instead.

    @atomicLoad

    1. @atomicLoad(comptime T: type, ptr: *const T, comptime ordering: builtin.AtomicOrder) T

    This builtin function atomically dereferences a pointer and returns the value.

    T must be a pointer type, a bool, or an integer whose bit count meets these requirements:

    • At least 8
    • At most the same as usize
    • Power of 2

    TODO right now bool is not accepted. Also I think we could make non powers of 2 work fine, maybe we can remove this restriction

    @atomicRmw

    1. @atomicRmw(comptime T: type, ptr: *T, comptime op: builtin.AtomicRmwOp, operand: T, comptime ordering: builtin.AtomicOrder) T

    This builtin function atomically modifies memory and then returns the previous value.

    T must be a pointer type, a bool, or an integer whose bit count meets these requirements:

    • At least 8
    • At most the same as usize
    • Power of 2

    TODO right now bool is not accepted. Also I think we could make non powers of 2 work fine, maybe we can remove this restriction

    @bitCast

    1. @bitCast(comptime DestType: type, value: var) DestType

    Converts a value of one type to another type.

    Asserts that @sizeOf(@typeOf(value)) == @sizeOf(DestType).

    Asserts that @typeId(DestType) != @import("builtin").TypeId.Pointer. Use @ptrCast or @intToPtr if you need this.

    Can be used for these things for example:

    • Convert f32 to u32 bits
    • Convert i32 to u32 preserving twos complement

    Works at compile-time if value is known at compile time. It's a compile error to bitcast a struct to a scalar type of the same size since structs have undefined layout. However if the struct is packed then it works.

    @bitOffsetOf

    1. @bitOffsetOf(comptime T: type, comptime field_name: [] const u8) comptime_int

    Returns the bit offset of a field relative to its containing struct.

    For non , this will always be divisible by 8. For packed structs, non-byte-aligned fields will share a byte offset, but they will have different bit offsets.

    See also:

    @boolToInt

    1. @boolToInt(value: bool) u1

    Converts true to u1(1) and false to u1(0).

    If the value is known at compile-time, the return type is comptime_int instead of u1.

    @breakpoint

    1. @breakpoint()

    This function inserts a platform-specific debug trap instruction which causes debuggers to break there.

    This function is only valid within function scope.

    @bswap

    1. @bswap(comptime T: type, value: T) T

    T must be an integer type with bit count evenly divisible by 8.

    Swaps the byte order of the integer. This converts a big endian integer to a little endian integer, and converts a little endian integer to a big endian integer.

    @bitreverse

    1. @bitreverse(comptime T: type, value: T) T

    T accepts any integer type.

    Reverses the bitpattern of an integer value, including the sign bit if applicable.

    For example 0b10110110 (u8 = 182, i8 = -74) becomes 0b01101101 (u8 = 109, i8 = 109).

    @byteOffsetOf

    1. @byteOffsetOf(comptime T: type, comptime field_name: [] const u8) comptime_int

    Returns the byte offset of a field relative to its containing struct.

    See also:

    @bytesToSlice

    1. @bytesToSlice(comptime Element: type, bytes: []u8) []Element

    Converts a slice of bytes or array of bytes into a slice of Element. The resulting slice has the same pointer properties as the parameter.

    Attempting to convert a number of bytes with a length that does not evenly divide into a slice of elements results in safety-protected .

    @cDefine

    1. @cDefine(comptime name: []u8, value)

    This function can only occur inside @cImport.

    This appends #define $name $value to the @cImport temporary buffer.

    To define without a value, like this:

    1. #define _GNU_SOURCE

    Use the void value, like this:

    1. @cDefine("_GNU_SOURCE", {})

    See also:

    @cImport

    1. @cImport(expression) type

    This function parses C code and imports the functions, types, variables, and compatible macro definitions into a new empty struct type, and then returns that type.

    expression is interpreted at compile time. The builtin functions @cInclude, @cDefine, and @cUndef work within this expression, appending to a temporary buffer which is then parsed as C code.

    Usually you should only have one @cImport in your entire application, because it saves the compiler from invoking clang multiple times, and prevents inline functions from being duplicated.

    Reasons for having multiple @cImport expressions would be:

    • To avoid a symbol collision, for example if foo.h and bar.h both #define CONNECTION_COUNT
    • To analyze the C code with different preprocessor defines

    See also:

    @cInclude

    1. @cInclude(comptime path: []u8)

    This function can only occur inside @cImport.

    This appends #include <$path>\n to the c_import temporary buffer.

    See also:

    @clz

    1. @clz(x: T) U

    This function counts the number of leading zeroes in x which is an integer type T.

    The return type U is an unsigned integer with the minimum number of bits that can represent the value T.bit_count.

    If x is zero, @clz returns T.bit_count.

    See also:

    @cmpxchgStrong

    1. @cmpxchgStrong(comptime T: type, ptr: *T, expected_value: T, new_value: T, success_order: AtomicOrder, fail_order: AtomicOrder) ?T

    This function performs a strong atomic compare exchange operation. It's the equivalent of this code, except atomic:

    1. fn cmpxchgStrongButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_value: T) ?T {
    2. const old_value = ptr.*;
    3. if (old_value == expected_value) {
    4. ptr.* = new_value;
    5. return null;
    6. } else {
    7. return old_value;
    8. }
    9. }

    If you are using cmpxchg in a loop, is the better choice, because it can be implemented more efficiently in machine instructions.

    AtomicOrder can be found with @import("builtin").AtomicOrder.

    @typeOf(ptr).alignment must be >= @sizeOf(T).

    See also:

    @cmpxchgWeak

    1. @cmpxchgWeak(comptime T: type, ptr: *T, expected_value: T, new_value: T, success_order: AtomicOrder, fail_order: AtomicOrder) ?T

    This function performs a weak atomic compare exchange operation. It's the equivalent of this code, except atomic:

    1. fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_value: T) ?T {
    2. const old_value = ptr.*;
    3. if (old_value == expected_value and usuallyTrueButSometimesFalse()) {
    4. ptr.* = new_value;
    5. return null;
    6. } else {
    7. return old_value;
    8. }
    9. }

    If you are using cmpxchg in a loop, the sporadic failure will be no problem, and cmpxchgWeak is the better choice, because it can be implemented more efficiently in machine instructions. However if you need a stronger guarantee, use @cmpxchgStrong.

    AtomicOrder can be found with @import("builtin").AtomicOrder.

    @typeOf(ptr).alignment must be >= @sizeOf(T).

    See also:

    @compileError

    1. @compileError(comptime msg: []u8)

    This function, when semantically analyzed, causes a compile error with the message msg.

    There are several ways that code avoids being semantically checked, such as using if or switch with compile time constants, and comptime functions.

    @compileLog

    1. @compileLog(args: ...)

    This function prints the arguments passed to it at compile-time.

    To prevent accidentally leaving compile log statements in a codebase, a compilation error is added to the build, pointing to the compile log statement. This error prevents code from being generated, but does not otherwise interfere with analysis.

    This function can be used to do "printf debugging" on compile-time executing code.

    test.zig

    1. const warn = @import("std").debug.warn;
    2. const num1 = blk: {
    3. var val1: i32 = 99;
    4. @compileLog("comptime val1 = ", val1);
    5. val1 = val1 + 1;
    6. break :blk val1;
    7. };
    8. test "main" {
    9. @compileLog("comptime in main");
    10. warn("Runtime in main, num1 = {}.\n", num1);
    11. }
    1. $ zig test test.zig
    2. | "comptime in main"
    3. | "comptime val1 = ", 99
    4. /home/andy/dev/zig/docgen_tmp/test.zig:11:5: error: found compile log statement
    5. @compileLog("comptime in main");
    6. ^
    7. /home/andy/dev/zig/docgen_tmp/test.zig:5:5: error: found compile log statement
    8. @compileLog("comptime val1 = ", val1);
    9. ^

    will ouput:

    If all @compileLog calls are removed or not encountered by analysis, the program compiles successfully and the generated executable prints:

    test.zig

    1. const warn = @import("std").debug.warn;
    2. const num1 = blk: {
    3. var val1: i32 = 99;
    4. val1 = val1 + 1;
    5. break :blk val1;
    6. };
    7. test "main" {
    8. warn("Runtime in main, num1 = {}.\n", num1);
    9. }
    1. $ zig test test.zig
    2. Test 1/1 main...Runtime in main, num1 = 100.
    3. OK
    4. All tests passed.

    @ctz

    1. @ctz(x: T) U

    This function counts the number of trailing zeroes in x which is an integer type T.

    The return type U is an unsigned integer with the minimum number of bits that can represent the value T.bit_count.

    If x is zero, @ctz returns T.bit_count.

    See also:

    @cUndef

    1. @cUndef(comptime name: []u8)

    This function can only occur inside @cImport.

    This appends #undef $name to the @cImport temporary buffer.

    See also:

    @divExact

    1. @divExact(numerator: T, denominator: T) T
    • @divExact(6, 3) == 2
    • @divExact(a, b) * b == a

    For a function that returns a possible error code, use @import("std").math.divExact.

    See also:

    @divFloor

    1. @divFloor(numerator: T, denominator: T) T

    Floored division. Rounds toward negative infinity. For unsigned integers it is the same as numerator / denominator. Caller guarantees denominator != 0 and !(@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1).

    • @divFloor(-5, 3) == -2
    • @divFloor(a, b) + @mod(a, b) == a

    For a function that returns a possible error code, use @import("std").math.divFloor.

    See also:

    @divTrunc

    1. @divTrunc(numerator: T, denominator: T) T

    Truncated division. Rounds toward zero. For unsigned integers it is the same as numerator / denominator. Caller guarantees denominator != 0 and !(@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1).

    • @divTrunc(-5, 3) == -1
    • @divTrunc(a, b) + @rem(a, b) == a

    For a function that returns a possible error code, use @import("std").math.divTrunc.

    See also:

    @embedFile

    1. @embedFile(comptime path: []const u8) [X]u8

    This function returns a compile time constant fixed-size array with length equal to the byte count of the file given by path. The contents of the array are the contents of the file.

    path is absolute or relative to the current file, just like @import.

    See also:

    @enumToInt

    1. @enumToInt(enum_or_tagged_union: var) var

    Converts an enumeration value into its integer tag type. When a tagged union is passed, the tag value is used as the enumeration value.

    If there is only one possible enum value, the resut is a comptime_int known at comptime.

    See also:

    1. @errorName(err: anyerror) []const u8

    This function returns the string representation of an error. The string representation of error.OutOfMem is "OutOfMem".

    If there are no calls to @errorName in an entire application, or all calls have a compile-time known value for err, then no error name table will be generated.

    @errorReturnTrace

    1. @errorReturnTrace() ?*builtin.StackTrace

    If the binary is built with error return tracing, and this function is invoked in a function that calls a function with an error or error union return type, returns a stack trace object. Otherwise returns null.

    @errorToInt

    1. @errorToInt(err: var) @IntType(false, @sizeOf(anyerror) * 8)

    Supports the following types:

    Converts an error to the integer representation of an error.

    It is generally recommended to avoid this cast, as the integer representation of an error is not stable across source code changes.

    See also:

    @errSetCast

    1. @errSetCast(comptime T: DestType, value: var) DestType

    Converts an error value from one error set to another error set. Attempting to convert an error which is not in the destination error set results in safety-protected .

    @export

    Creates a symbol in the output object file.

    This function can be called from a comptime block to conditionally export symbols. When target is a function with the C calling convention and linkage is Strong, this is equivalent to the export keyword used on a function:

    test.zig

    1. const builtin = @import("builtin");
    2. comptime {
    3. @export("foo", internalName, builtin.GlobalLinkage.Strong);
    4. }
    5. extern fn internalName() void {}
    1. $ zig build-obj test.zig

    This is equivalent to:

    test.zig

    1. export fn foo() void {}
    1. $ zig build-obj test.zig

    Note that even when using export, @"foo" syntax can be used to choose any string for the symbol name:

    test.zig

    1. export fn @"A function name that is a complete sentence."() void {}
    1. $ zig build-obj test.zig

    When looking at the resulting object, you can see the symbol is used verbatim:

    1. 00000000000001f0 T A function name that is a complete sentence.

    See also:

    @fence

    1. @fence(order: AtomicOrder)

    The fence function is used to introduce happens-before edges between operations.

    AtomicOrder can be found with @import("builtin").AtomicOrder.

    See also:

    @field

    1. @field(lhs: var, comptime field_name: []const u8) (field)

    Preforms field access equivalent to lhs.field_name, except instead of the field "field_name", it accesses the field named by the string value of field_name.

    @fieldParentPtr

    1. @fieldParentPtr(comptime ParentType: type, comptime field_name: []const u8,
    2. field_ptr: *T) *ParentType

    Given a pointer to a field, returns the base pointer of a struct.

    @floatCast

    1. @floatCast(comptime DestType: type, value: var) DestType

    Convert from one float type to another. This cast is safe, but may cause the numeric value to lose precision.

    @floatToInt

    1. @floatToInt(comptime DestType: type, float: var) DestType

    Converts the integer part of a floating point number to the destination type.

    If the integer part of the floating point number cannot fit in the destination type, it invokes safety-checked .

    See also:

    @frameAddress

    1. @frameAddress() usize

    This function returns the base pointer of the current stack frame.

    The implications of this are target specific and not consistent across all platforms. The frame address may not be available in release mode due to aggressive optimizations.

    This function is only valid within function scope.

    @handle

    1. @handle()

    This function returns a promise->T type, where T is the return type of the async function in scope.

    This function is only valid within an async function scope.

    @import

    1. @import(comptime path: []u8) type

    This function finds a zig file corresponding to and adds it to the build, if it is not already added.

    Zig source files are implicitly structs, with a name equal to the file's basename with the extension truncated. @import returns the struct type corresponding to the file.

    Declarations which have the pub keyword may be referenced from a different source file than the one they are declared in.

    path can be a relative or absolute path, or it can be the name of a package. If it is a relative path, it is relative to the file that contains the @import function call.

    The following packages are always available:

    • @import("std") - Zig Standard Library
    • @import("builtin") - Compiler-provided types and variables. The command zig builtin outputs the source to stdout for reference.

    See also:

    @inlineCall

    1. @inlineCall(function: X, args: ...) Y

    This calls a function, in the same way that invoking an expression with parentheses does:

    test.zig

    1. const assert = @import("std").debug.assert;
    2. test "inline function call" {
    3. assert(@inlineCall(add, 3, 9) == 12);
    4. }
    5. fn add(a: i32, b: i32) i32 { return a + b; }
    1. $ zig test test.zig
    2. Test 1/1 inline function call...OK
    3. All tests passed.

    Unlike a normal function call, however, @inlineCall guarantees that the call will be inlined. If the call cannot be inlined, a compile error is emitted.

    See also:

    @intCast

    1. @intCast(comptime DestType: type, int: var) DestType

    Converts an integer to another integer while keeping the same numerical value. Attempting to convert a number which is out of range of the destination type results in safety-protected Undefined Behavior.

    @intToEnum

    1. @intToEnum(comptime DestType: type, int_value: @TagType(DestType)) DestType

    Converts an integer into an value.

    Attempting to convert an integer which represents no value in the chosen enum type invokes safety-checked Undefined Behavior.

    See also:

    @intToError

    1. @intToError(value: @IntType(false, @sizeOf(anyerror) * 8)) anyerror

    Converts from the integer representation of an error into The Global Error Set type.

    It is generally recommended to avoid this cast, as the integer representation of an error is not stable across source code changes.

    Attempting to convert an integer that does not correspond to any error results in safety-protected .

    See also:

    @intToFloat

    1. @intToFloat(comptime DestType: type, int: var) DestType

    Converts an integer to the closest floating point representation. To convert the other way, use . This cast is always safe.

    @intToPtr

    1. @intToPtr(comptime DestType: type, address: usize) DestType

    Converts an integer to a pointer. To convert the other way, use .

    If the destination pointer type does not allow address zero and address is zero, this invokes safety-checked Undefined Behavior.

    @IntType

    1. @IntType(comptime is_signed: bool, comptime bit_count: u16) type

    This function returns an integer type with the given signness and bit count. The maximum bit count for an integer type is 65535.

    @memberCount

    1. @memberCount(comptime T: type) comptime_int

    This function returns the number of members in a struct, enum, or union type.

    The result is a compile time constant.

    It does not include functions, variables, or constants.

    @memberName

    1. @memberName(comptime T: type, comptime index: usize) [N]u8

    Returns the field name of a struct, union, or enum.

    The result is a compile time constant.

    It does not include functions, variables, or constants.

    @memberType

    1. @memberType(comptime T: type, comptime index: usize) type

    Returns the field type of a struct or union.

    @memcpy

    1. @memcpy(noalias dest: [*]u8, noalias source: [*]const u8, byte_count: usize)

    This function copies bytes from one region of memory to another. dest and source are both pointers and must not overlap.

    This function is a low level intrinsic with no safety mechanisms. Most code should not use this function, instead using something like this:

    1. for (source[0..byte_count]) |b, i| dest[i] = b;

    The optimizer is intelligent enough to turn the above snippet into a memcpy.

    There is also a standard library function for this:

    1. const mem = @import("std").mem;
    2. mem.copy(u8, dest[0..byte_count], source[0..byte_count]);

    @memset

    1. @memset(dest: [*]u8, c: u8, byte_count: usize)

    This function sets a region of memory to c. dest is a pointer.

    1. for (dest[0..byte_count]) |*b| b.* = c;

    The optimizer is intelligent enough to turn the above snippet into a memset.

    There is also a standard library function for this:

    1. const mem = @import("std").mem;
    2. mem.set(u8, dest, c);

    @mod

    1. @mod(numerator: T, denominator: T) T

    Modulus division. For unsigned integers this is the same as numerator % denominator. Caller guarantees denominator > 0.

    • @mod(-5, 3) == 1
    • @divFloor(a, b) + @mod(a, b) == a

    For a function that returns an error code, see @import("std").math.mod.

    See also:

    @mulWithOverflow

    1. @mulWithOverflow(comptime T: type, a: T, b: T, result: *T) bool

    Performs result.* = a * b. If overflow or underflow occurs, stores the overflowed bits in result and returns true. If no overflow or underflow occurs, returns false.

    @newStackCall

    1. @newStackCall(new_stack: []u8, function: var, args: ...) var

    This calls a function, in the same way that invoking an expression with parentheses does. However, instead of using the same stack as the caller, the function uses the stack provided in the new_stack parameter.

    test.zig

    1. const std = @import("std");
    2. const assert = std.debug.assert;
    3. var new_stack_bytes: [1024]u8 = undefined;
    4. test "calling a function with a new stack" {
    5. const arg = 1234;
    6. const a = @newStackCall(new_stack_bytes[0..512], targetFunction, arg);
    7. const b = @newStackCall(new_stack_bytes[512..], targetFunction, arg);
    8. _ = targetFunction(arg);
    9. assert(arg == 1234);
    10. assert(a < b);
    11. }
    12. fn targetFunction(x: i32) usize {
    13. assert(x == 1234);
    14. var local_variable: i32 = 42;
    15. const ptr = &local_variable;
    16. ptr.* += 1;
    17. assert(local_variable == 43);
    18. return @ptrToInt(ptr);
    19. }
    1. $ zig test test.zig
    2. Test 1/1 calling a function with a new stack...OK
    3. All tests passed.

    @noInlineCall

    1. @noInlineCall(function: var, args: ...) var

    This calls a function, in the same way that invoking an expression with parentheses does:

    test.zig

    1. const assert = @import("std").debug.assert;
    2. test "noinline function call" {
    3. assert(@noInlineCall(add, 3, 9) == 12);
    4. }
    5. fn add(a: i32, b: i32) i32 {
    6. return a + b;
    7. }
    1. $ zig test test.zig
    2. Test 1/1 noinline function call...OK
    3. All tests passed.

    Unlike a normal function call, however, @noInlineCall guarantees that the call will not be inlined. If the call must be inlined, a compile error is emitted.

    See also:

    Creates a new type with an unknown (but non-zero) size and alignment.

    This is typically used for type safety when interacting with C code that does not expose struct details. Example:

    test.zig

    1. const Derp = @OpaqueType();
    2. const Wat = @OpaqueType();
    3. extern fn bar(d: *Derp) void;
    4. export fn foo(w: *Wat) void {
    5. bar(w);
    6. }
    7. test "call foo" {
    8. foo(undefined);
    9. }
    1. $ zig test test.zig
    2. /home/andy/dev/zig/docgen_tmp/test.zig:6:9: error: expected type '*Derp', found '*Wat'
    3. bar(w);
    4. ^
    5. /home/andy/dev/zig/docgen_tmp/test.zig:6:9: note: pointer type child 'Wat' cannot cast into pointer type child 'Derp'
    6. bar(w);
    7. ^

    @panic

    1. @panic(message: []const u8) noreturn

    Invokes the panic handler function. By default the panic handler function calls the public panic function exposed in the root source file, or if there is not one specified, invokes the one provided in std/special/panic.zig.

    Generally it is better to use @import("std").debug.panic. However, @panic can be useful for 2 scenarios:

    • From library code, calling the programmer's panic function if they exposed one in the root source file.
    • When mixing C and Zig code, calling the canonical panic implementation across multiple .o files.

    See also:

    @popCount

    1. @popCount(integer: var) var

    Counts the number of bits set in an integer.

    If integer is known at comptime, the return type is comptime_int. Otherwise, the return type is an unsigned integer with the minimum number of bits that can represent the bit count of the integer type.

    See also:

    @ptrCast

    1. @ptrCast(comptime DestType: type, value: var) DestType

    Converts a pointer of one type to a pointer of another type.

    are allowed. Casting an optional pointer which is null to a non-optional pointer invokes safety-checked .

    @ptrToInt

    1. @ptrToInt(value: var) usize

    Converts value to a usize which is the address of the pointer. value can be one of these types:

    • *T
    • ?*T
    • fn()
    • ?fn()

    To convert the other way, use @intToPtr

    @rem

    1. @rem(numerator: T, denominator: T) T

    Remainder division. For unsigned integers this is the same as numerator % denominator. Caller guarantees denominator > 0.

    • @rem(-5, 3) == -2
    • @divTrunc(a, b) + @rem(a, b) == a

    For a function that returns an error code, see @import("std").math.rem.

    See also:

    @returnAddress

    1. @returnAddress() usize

    This function returns the address of the next machine code instruction that will be executed when the current function returns.

    The implications of this are target specific and not consistent across all platforms.

    This function is only valid within function scope. If the function gets inlined into a calling function, the returned address will apply to the calling function.

    @setAlignStack

    1. @setAlignStack(comptime alignment: u29)

    Ensures that a function will have a stack alignment of at least alignment bytes.

    @setCold

    1. @setCold(is_cold: bool)

    Tells the optimizer that a function is rarely called.

    @setEvalBranchQuota

    1. @setEvalBranchQuota(new_quota: usize)

    Changes the maximum number of backwards branches that compile-time code execution can use before giving up and making a compile error.

    If the new_quota is smaller than the default quota (1000) or a previously explicitly set quota, it is ignored.

    Example:

    test.zig

    1. test "foo" {
    2. comptime {
    3. var i = 0;
    4. while (i < 1001) : (i += 1) {}
    5. }
    6. }
    1. $ zig test test.zig
    2. /home/andy/dev/zig/docgen_tmp/test.zig:4:9: error: evaluation exceeded 1000 backwards branches
    3. while (i < 1001) : (i += 1) {}
    4. ^

    Now we use @setEvalBranchQuota:

    test.zig

    1. test "foo" {
    2. comptime {
    3. @setEvalBranchQuota(1001);
    4. var i = 0;
    5. while (i < 1001) : (i += 1) {}
    6. }
    7. }
    1. $ zig test test.zig
    2. Test 1/1 foo...OK
    3. All tests passed.

    See also:

    @setFloatMode

    1. @setFloatMode(mode: @import("builtin").FloatMode)

    Sets the floating point mode of the current scope. Possible values are:

    1. pub const FloatMode = enum {
    2. Strict,
    3. Optimized,
    4. };
    • Strict (default) - Floating point operations follow strict IEEE compliance.
    • Optimized - Floating point operations may do all of the following:
      • Assume the arguments and result are not NaN. Optimizations are required to retain defined behavior over NaNs, but the value of the result is undefined.
      • Assume the arguments and result are not +/-Inf. Optimizations are required to retain defined behavior over +/-Inf, but the value of the result is undefined.
      • Treat the sign of a zero argument or result as insignificant.
      • Use the reciprocal of an argument rather than perform division.
      • Perform floating-point contraction (e.g. fusing a multiply followed by an addition into a fused multiply-and-add).
      • Perform algebraically equivalent transformations that may change results in floating point (e.g. reassociate). This is equivalent to -ffast-math in GCC.

    The floating point mode is inherited by child scopes, and can be overridden in any scope. You can set the floating point mode in a struct or module scope by using a comptime block.

    See also:

    @setGlobalLinkage

    1. @setGlobalLinkage(global_variable_name, comptime linkage: GlobalLinkage)

    GlobalLinkage can be found with @import("builtin").GlobalLinkage.

    See also:

    @setRuntimeSafety

    1. @setRuntimeSafety(safety_on: bool)

    Sets whether runtime safety checks are enabled for the scope that contains the function call.

    test.zig

    1. test "@setRuntimeSafety" {
    2. // The builtin applies to the scope that it is called in. So here, integer overflow
    3. // will not be caught in ReleaseFast and ReleaseSmall modes:
    4. // var x: u8 = 255;
    5. // x += 1; // undefined behavior in ReleaseFast/ReleaseSmall modes.
    6. {
    7. // However this block has safety enabled, so safety checks happen here,
    8. // even in ReleaseFast and ReleaseSmall modes.
    9. @setRuntimeSafety(true);
    10. var x: u8 = 255;
    11. x += 1;
    12. {
    13. // The value can be overridden at any scope. So here integer overflow
    14. // would not be caught in any build mode.
    15. @setRuntimeSafety(false);
    16. // var x: u8 = 255;
    17. // x += 1; // undefined behavior in all build modes.
    18. }
    19. }
    20. }
    1. $ zig test test.zig --release-fast
    2. Test 1/1 @setRuntimeSafety...integer overflow
    3. Tests failed. Use the following command to reproduce the failure:
    4. /home/andy/dev/zig/docgen_tmp/test

    @shlExact

    1. @shlExact(value: T, shift_amt: Log2T) T

    Performs the left shift operation (<<). Caller guarantees that the shift will not shift any 1 bits out.

    The type of shift_amt is an unsigned integer with log2(T.bit_count) bits. This is because shift_amt >= T.bit_count is undefined behavior.

    See also:

    @shlWithOverflow

    1. @shlWithOverflow(comptime T: type, a: T, shift_amt: Log2T, result: *T) bool

    Performs result.* = a << b. If overflow or underflow occurs, stores the overflowed bits in result and returns true. If no overflow or underflow occurs, returns false.

    The type of shift_amt is an unsigned integer with log2(T.bit_count) bits. This is because shift_amt >= T.bit_count is undefined behavior.

    See also:

    @shrExact

    1. @shrExact(value: T, shift_amt: Log2T) T

    Performs the right shift operation (>>). Caller guarantees that the shift will not shift any 1 bits out.

    The type of shift_amt is an unsigned integer with log2(T.bit_count) bits. This is because shift_amt >= T.bit_count is undefined behavior.

    See also:

    @sizeOf

    1. @sizeOf(comptime T: type) comptime_int

    This function returns the number of bytes it takes to store T in memory. The result is a target-specific compile time constant.

    This size may contain padding bytes. If there were two consecutive T in memory, this would be the offset in bytes between element at index 0 and the element at index 1. For , consider whether you want to use @sizeOf(T) or @typeInfo(T).Int.bits.

    See also:

    @sliceToBytes

    1. @sliceToBytes(value: var) []u8

    Converts a slice or array to a slice of u8. The resulting slice has the same properties as the parameter.

    @sqrt

    1. @sqrt(comptime T: type, value: T) T

    Performs the square root of a floating point number. Uses a dedicated hardware instruction when available. Currently only supports f32 and f64 at runtime. f128 at runtime is TODO.

    This is a low-level intrinsic. Most code can use std.math.sqrt instead.

    @subWithOverflow

    1. @subWithOverflow(comptime T: type, a: T, b: T, result: *T) bool

    Performs result.* = a - b. If overflow or underflow occurs, stores the overflowed bits in result and returns true. If no overflow or underflow occurs, returns false.

    @tagName

    1. @tagName(value: var) []const u8

    Converts an enum value or union value to a slice of bytes representing the name.

    @TagType

    1. @TagType(T: type) type

    For an enum, returns the integer type that is used to store the enumeration value.

    For a union, returns the enum type that is used to store the tag value.

    @This

    1. @This() type

    Returns the innermost struct or union that this function call is inside. This can be useful for an anonymous struct that needs to refer to itself:

    test.zig

    1. const std = @import("std");
    2. var items = []i32{ 1, 2, 3, 4 };
    3. const list = List(i32){ .items = items[0..] };
    4. assert(list.length() == 4);
    5. }
    6. fn List(comptime T: type) type {
    7. return struct {
    8. const Self = @This();
    9. items: []T,
    10. fn length(self: Self) usize {
    11. return self.items.len;
    12. }
    13. };
    14. }
    1. $ zig test test.zig
    2. Test 1/1 @This()...OK
    3. All tests passed.

    When @This() is used at global scope, it returns a reference to the current import. There is a proposal to remove the import type and use an empty struct type instead. See #1047 for details.

    @truncate

    1. @truncate(comptime T: type, integer: var) T

    This function truncates bits from an integer type, resulting in a smaller integer type.

    The following produces a crash in mode and Undefined Behavior in mode:

    1. const a: u16 = 0xabcd;
    2. const b: u8 = u8(a);

    However this is well defined and working code:

    1. const a: u16 = 0xabcd;
    2. const b: u8 = @truncate(u8, a);
    3. // b is now 0xcd

    This function always truncates the significant bits of the integer, regardless of endianness on the target platform.

    If T is comptime_int, then this is semantically equivalent to an implicit cast.

    @typeId

    1. @typeId(comptime T: type) @import("builtin").TypeId

    Returns which kind of type something is. Possible values:

    1. pub const TypeId = enum {
    2. Type,
    3. Void,
    4. Bool,
    5. NoReturn,
    6. Int,
    7. Float,
    8. Pointer,
    9. Array,
    10. Struct,
    11. ComptimeFloat,
    12. ComptimeInt,
    13. Undefined,
    14. Null,
    15. Optional,
    16. ErrorUnion,
    17. Error,
    18. Enum,
    19. Union,
    20. Fn,
    21. Block,
    22. BoundFn,
    23. ArgTuple,
    24. Opaque,
    25. };

    @typeInfo

    1. @typeInfo(comptime T: type) @import("builtin").TypeInfo

    Returns information on the type. Returns a value of the following union:

    1. pub const TypeInfo = union(TypeId) {
    2. Type: void,
    3. Void: void,
    4. Bool: void,
    5. NoReturn: void,
    6. Int: Int,
    7. Float: Float,
    8. Pointer: Pointer,
    9. Array: Array,
    10. Struct: Struct,
    11. ComptimeFloat: void,
    12. ComptimeInt: void,
    13. Undefined: void,
    14. Null: void,
    15. Optional: Optional,
    16. ErrorUnion: ErrorUnion,
    17. ErrorSet: ErrorSet,
    18. Enum: Enum,
    19. Union: Union,
    20. Fn: Fn,
    21. BoundFn: Fn,
    22. ArgTuple: void,
    23. Opaque: void,
    24. Promise: Promise,
    25. Vector: Vector,
    26. EnumLiteral: void,
    27. pub const Int = struct {
    28. is_signed: bool,
    29. bits: comptime_int,
    30. };
    31. pub const Float = struct {
    32. bits: comptime_int,
    33. };
    34. pub const Pointer = struct {
    35. size: Size,
    36. is_const: bool,
    37. is_volatile: bool,
    38. alignment: comptime_int,
    39. child: type,
    40. is_allowzero: bool,
    41. pub const Size = enum {
    42. One,
    43. Many,
    44. Slice,
    45. C,
    46. };
    47. };
    48. pub const Array = struct {
    49. len: comptime_int,
    50. child: type,
    51. };
    52. pub const ContainerLayout = enum {
    53. Auto,
    54. Extern,
    55. Packed,
    56. };
    57. pub const StructField = struct {
    58. name: []const u8,
    59. offset: ?comptime_int,
    60. field_type: type,
    61. };
    62. pub const Struct = struct {
    63. layout: ContainerLayout,
    64. fields: []StructField,
    65. defs: []Definition,
    66. };
    67. pub const Optional = struct {
    68. child: type,
    69. };
    70. pub const ErrorUnion = struct {
    71. error_set: type,
    72. payload: type,
    73. };
    74. pub const Error = struct {
    75. name: []const u8,
    76. value: comptime_int,
    77. };
    78. pub const ErrorSet = ?[]Error;
    79. pub const EnumField = struct {
    80. name: []const u8,
    81. value: comptime_int,
    82. };
    83. pub const Enum = struct {
    84. layout: ContainerLayout,
    85. tag_type: type,
    86. fields: []EnumField,
    87. defs: []Definition,
    88. };
    89. pub const UnionField = struct {
    90. name: []const u8,
    91. enum_field: ?EnumField,
    92. field_type: type,
    93. };
    94. pub const Union = struct {
    95. layout: ContainerLayout,
    96. tag_type: ?type,
    97. fields: []UnionField,
    98. defs: []Definition,
    99. };
    100. pub const CallingConvention = enum {
    101. Unspecified,
    102. C,
    103. Cold,
    104. Naked,
    105. Stdcall,
    106. Async,
    107. };
    108. pub const FnArg = struct {
    109. is_generic: bool,
    110. is_noalias: bool,
    111. arg_type: ?type,
    112. };
    113. pub const Fn = struct {
    114. calling_convention: CallingConvention,
    115. is_generic: bool,
    116. is_var_args: bool,
    117. return_type: ?type,
    118. async_allocator_type: ?type,
    119. args: []FnArg,
    120. };
    121. pub const Promise = struct {
    122. child: ?type,
    123. };
    124. pub const Vector = struct {
    125. len: comptime_int,
    126. child: type,
    127. };
    128. pub const Definition = struct {
    129. name: []const u8,
    130. is_pub: bool,
    131. data: Data,
    132. pub const Data = union(enum) {
    133. Type: type,
    134. Var: type,
    135. Fn: FnDef,
    136. pub const FnDef = struct {
    137. fn_type: type,
    138. inline_type: Inline,
    139. calling_convention: CallingConvention,
    140. is_var_args: bool,
    141. is_extern: bool,
    142. is_export: bool,
    143. lib_name: ?[]const u8,
    144. return_type: type,
    145. arg_names: [][] const u8,
    146. pub const Inline = enum {
    147. Auto,
    148. Always,
    149. Never,
    150. };
    151. };
    152. };
    153. };
    154. };

    For , unions, , and error sets, the fields are guaranteed to be in the same order as declared. For declarations, the order is unspecified.

    @typeName

    1. @typeName(T: type) [N]u8

    This function returns the string representation of a type, as an array. It is equivalent to a string literal of the type name.

    @typeOf

    This function returns a compile-time constant, which is the type of the expression passed as an argument. The expression is evaluated.

    @Vector

    1. @Vector(comptime len: u32, comptime ElemType: type) type

    ElemType must be an , a float, or a .