2. Primitive Types

April 9, 2026 ยท View on GitHub

+++ title = "2. Primitive Types" weight = 2 +++

2. Primitive Types

TypeC EquivalentDescription
int, uintint32_t, uint32_t32-bit signed/unsigned integer
c_char, c_ucharchar, unsigned charC char / unsigned char (Interop)
c_short, c_ushortshort, unsigned shortC short / unsigned short (Interop)
c_int, c_uintint, unsigned intC int / unsigned int (Interop)
c_long, c_ulonglong, unsigned longC long / unsigned long (Interop)
c_longlong, c_ulonglonglong long, unsigned long longC long long / unsigned long long (Interop)
I8 .. I128 or i8 .. i128int8_t .. __int128_tSigned fixed-width integers
U8 .. U128 or u8 .. u128uint8_t .. __uint128_tUnsigned fixed-width integers
isize, usizeptrdiff_t, size_tPointer-sized integers
byteuint8_tAlias for U8
F32, F64 or f32, f64float, doubleFloating point numbers
boolbooltrue or false
charcharSingle character
stringchar*C-string (null-terminated)
U0, u0, voidvoidEmpty type
iN (for example, i256)_BitInt(N)Arbitrary bit-width signed integer (C23)
uN (for example, u42)unsigned _BitInt(N)Arbitrary bit-width unsigned integer (C23)
runeuint32_tUnicode scalar value (UTF-32 code point)

Literals

  • Integers: Decimal (123), Hex (0xFF), Octal (0o755), Binary (0b1011).
    • Note: Numbers with leading zeros are treated as decimal (0123 is 123), unlike C.
    • Note: Numbers can contain underscores for readability (1_000_000, 0b_1111_0000).
  • Floats: Standard (3.14), Scientific (1e-5, 1.2E3). Floating point numbers also support underscores (3_14.15_92).

Unicode and Runes

Zen C provides first-class support for Unicode scalar values via the rune type. A rune represents a single Unicode code point (encoded as a 32-bit unsigned integer).

LiteralDescription
'a'Standard ASCII character
'๐Ÿš€'Multi-byte Unicode character
'\u{2764}'Unicode escape sequence (Hex)
import "std.zc"

fn main() {
    let c = 'a';
    println "The character '{c}' has a code of {(int)c} in ASCII/Unicode";

    let code = 97;
    println "The code {code} corresponds to the character {(char)code}";

    let r: rune = '๐Ÿš€';
    println "The rune '{r}' has a code of {(uint)r} in Unicode";
    
    let r_code: uint = 128640;
    println "The code {r_code} corresponds to the rune '{(rune)r_code}'";

    let r_esc: rune = '\u{2764}';
    println "The rune '{r_esc}' has code {(uint)r_esc} (0x{(uint)r_esc:X})";
}

{% alert(type="important") %} Best Practices for Portable Code

  • Use Portable Types (int, uint, i64, u8, etc.) for all pure Zen C logic. int is guaranteed to be 32-bit signed on all architectures.
  • Use C Interop Types (c_int, c_char, c_long, c_ulong, c_longlong, c_ulonglong) only when interacting with C libraries (FFI). Their size varies by platform and C compiler (e.g. c_long size differs between Windows and Linux).
  • Use isize and usize for array indexing and memory pointer arithmetic. {% end %}