# Appendix C. Builtin Functions

### Appendix C. Builtin Functions

Builtin functions are part of the language. Their names begin with `@`.

This appendix gives the common builtins by purpose. It is not a complete replacement for the language reference.

### C.1 Import and Type Information

```zig
@import("std")
@This()
@TypeOf(x)
```

`@import` loads a package or source file.

```zig
const std = @import("std");
const math = @import("math.zig");
```

`@This` gives the current container type.

```zig
const Node = struct {
    const Self = @This();

    value: i32,
    next: ?*Self,
};
```

`@TypeOf` gives the type of an expression.

```zig
const T = @TypeOf(123);
```

### C.2 Size and Alignment

```zig
@sizeOf(T)
@alignOf(T)
@bitSizeOf(T)
@offsetOf(T, "field")
```

Example:

```zig
const std = @import("std");

pub fn main() void {
    std.debug.print("size = {d}\n", .{@sizeOf(u64)});
}
```

`@sizeOf` counts bytes. `@bitSizeOf` counts bits. `@alignOf` gives the ABI alignment.

### C.3 Type Conversion

```zig
@as(T, x)
@intCast(x)
@floatCast(x)
@ptrCast(p)
@alignCast(p)
@bitCast(x)
```

Examples:

```zig
const x: i32 = @intCast(n);
const y: f32 = @floatCast(z);
const p: *T = @ptrCast(raw);
```

Use casts where the program needs a precise type. Do not use casts to hide a bad design.

### C.4 Integer Conversion

```zig
@intFromFloat(x)
@floatFromInt(x)
@intFromEnum(x)
@enumFromInt(x)
@intFromPtr(p)
@ptrFromInt(addr)
```

Example:

```zig
const n: i32 = @intFromFloat(12.0);
const f: f64 = @floatFromInt(n);
```

Pointer-integer conversion is low-level code. It belongs in allocators, kernels, device code, and foreign interfaces.

### C.5 Arithmetic

```zig
@addWithOverflow(a, b)
@subWithOverflow(a, b)
@mulWithOverflow(a, b)
@shlWithOverflow(a, b)
```

Example:

```zig
const r = @addWithOverflow(a, b);
if (r[1] != 0) {
    return error.Overflow;
}
const sum = r[0];
```

The result contains the computed value and an overflow flag.

### C.6 Division and Remainder

```zig
@divExact(a, b)
@divFloor(a, b)
@divTrunc(a, b)
@mod(a, b)
@rem(a, b)
```

Example:

```zig
const q = @divFloor(a, b);
const r = @mod(a, b);
```

Use these when signed division must have a clear rule.

### C.7 Bit Operations

```zig
@clz(x)
@ctz(x)
@popCount(x)
@byteSwap(x)
@bitReverse(x)
```

Example:

```zig
const ones = @popCount(mask);
```

These map well to machine instructions on most targets.

### C.8 Memory

```zig
@memcpy(dest, source)
@memset(dest, value)
```

Example:

```zig
@memset(buf, 0);
@memcpy(dst, src);
```

The source and destination must have compatible lengths.

### C.9 Compile-Time Reflection

```zig
@typeInfo(T)
@Type(info)
@hasDecl(T, "name")
@hasField(T, "field")
@field(x, "name")
```

Example:

```zig
fn hasLen(comptime T: type) bool {
    return @hasField(T, "len");
}
```

Reflection is ordinary Zig code evaluated at compile time.

### C.10 Compile-Time Control

```zig
@compileError("message")
@compileLog(x)
```

Example:

```zig
fn requireInt(comptime T: type) void {
    if (@typeInfo(T) != .int) {
        @compileError("expected integer type");
    }
}
```

`@compileLog` is for debugging compile-time code. Remove it when finished.

### C.11 Calling and Inlining

```zig
@call(modifier, function, args)
```

The modifier controls call behavior.

Common forms include ordinary calls, inline calls, and never-inline calls.

Most code should use normal function-call syntax.

### C.12 Atomics

```zig
@atomicLoad(T, ptr, ordering)
@atomicStore(T, ptr, value, ordering)
@atomicRmw(T, ptr, op, value, ordering)
@cmpxchgWeak(T, ptr, expected, new_value, success_order, fail_order)
@cmpxchgStrong(T, ptr, expected, new_value, success_order, fail_order)
```

Example:

```zig
const old = @atomicRmw(u32, &counter, .add, 1, .monotonic);
```

Atomics are for shared memory between threads or hardware agents. Use the weakest ordering that proves correct.

### C.13 Error Return Tracing

```zig
@errorReturnTrace()
```

This returns the current error return trace when tracing is enabled.

```zig
if (@errorReturnTrace()) |trace| {
    _ = trace;
}
```

### C.14 Source Location

```zig
@src()
```

Example:

```zig
const here = @src();
```

It returns compile-time information about the current source location.

### C.15 Panic and Trap

```zig
@panic("message")
@trap()
```

`@panic` stops with a message.

```zig
if (bad) {
    @panic("invalid state");
}
```

`@trap` emits a target trap instruction.

### C.16 Branch Hints and Optimization

```zig
@branchHint(.likely)
@branchHint(.unlikely)
@setEvalBranchQuota(n)
```

Branch hints are rarely needed.

```zig
if (fast_path) {
    @branchHint(.likely);
    runFast();
}
```

`@setEvalBranchQuota` raises the branch quota for compile-time evaluation.

### C.17 ABI and Target

```zig
@cImport(...)
@cInclude("file.h")
@cDefine("NAME", "VALUE")
@cUndef("NAME")
```

Example:

```zig
const c = @cImport({
    @cInclude("stdio.h");
});
```

These are used for C interoperation.

### C.18 Assembly

```zig
asm volatile (...)
```

Inline assembly is target-specific and should be isolated behind small functions.

```zig
fn halt() noreturn {
    while (true) {
        asm volatile ("hlt");
    }
}
```

### C.19 Common Rule

A builtin should make the program more explicit. If it only makes the program clever, remove it.

