CString

public struct CString { /* private fields */ }

A null-terminated, non-owning byte pointer suitable for @extern(.C) boundaries.

CString is an FFI shim — it carries a Pointer[UInt8] that the C side will treat as const char *, but it does not own the memory. The pointer's lifetime, validity, and disposal are entirely the caller's responsibility. Two common ownership patterns: (1) the C side returns a pointer into static or environ memory — wrap it in a CString and read, but never free; (2) the Kestrel side allocates via String.toCString() — the caller must free() the result.

Examples

@extern(.C, mangleName: "puts") func puts(s: CString) -> Int32 let cstr = "Hello, C!".toCString(); puts(cstr); cstr.free();

Safety

  • The pointer must remain valid for as long as the CString is used.
  • The pointed-to bytes must end with a 0 terminator.
  • length is computed by scanning to the terminator — quadratic if you build long strings by repeated reads of length.
  • The caller chooses whether free() is appropriate (yes for self-allocated, no for borrowed pointers).

Representation

A single Pointer[UInt8] field. No length is cached.

Memory Model

Non-owning. Conforms to FFISafe so it passes through @extern(.C) signatures unchanged.

Properties

public var isNull: Bool { get }

True if the wrapped pointer is null.

A null CString should not be passed to a C function that expects a string; check this before calling.

public var length: Int64 { get }

Length of the string in bytes, excluding the null terminator.

Computed by linear scan — O(n). Cache the result if you need it more than once. Returns 0 for a null pointer (defensive: avoids dereferencing).

public var raw: Pointer[UInt8]

The underlying pointer to the null-terminated bytes.

Initializers

public init(raw: Pointer[UInt8])

Wraps an existing pointer as a CString.

Performs no validation — the caller affirms that the pointer is null or points at null-terminated memory.

Safety

  • rawPtr must be null or point at a null-terminated byte sequence.
  • The pointed-to bytes must remain valid for the lifetime of the CString.
  • The caller decides whether free() is later appropriate.

Methods

public func free()

Frees the buffer pointed to by this CString via libc free.

No-op when the pointer is null. After this call the CString is dangling — do not read its bytes or call any other method that touches the pointer.

Safety

Only call this on CStrings whose pointer was produced by a prior malloc (e.g. via String.toCString()). Calling on a borrowed pointer (returned by getenv, a string literal, etc.) is undefined behaviour.

Defined in lang/std/ffi/cstring.ks