C+
Systems · View as Markdown
v0.0.27 is a macOS / AppKit release. That is the supported path. Other platforms are not recommended; wait for a later version.

Attributes

Attributes are compiler-known metadata: they flip flags the compiler reads, or (for contracts) emit the same checks assert uses. They never run user logic or expand into macros. An unknown attribute is E0354.

#[test]: register a test function

#[test]
fn it_adds() {
    let r: i32 = add(2, 3);
    assert r == 5;
}

Run with cpc test. The assert intrinsic sets a failure flag in a test build and traps in a regular build.

Function contracts: #[requires] and #[ensures]

Machine-checked preconditions and postconditions on a fn or method. Each argument is a pure bool expression; the compiler emits it as an assert (traps on violation; test builds report). See Functions.

#[requires(n > 0)]
#[ensures(result >= n)]
fn bump(n: i32) -> i32 { return n +% 1; }

A non-bool or impure expression is E0924. Naming result on a function that returns nothing is E0928.

#[repr(C)], packed layout, bitfields, and #[link_name]

Layout and symbol control for FFI. Covered on the FFI page:

  • #[repr(C)] promises platform C-ABI layout for a struct or union that crosses an extern fn boundary.
  • #[repr(C, packed)] / #[repr(C, packed = N)] remove padding, or cap field alignment at N.
  • #[bits(N)] on an integer field packs a C bitfield.
  • #[link_name] binds one C symbol under several typed shapes.
  • #[repr(u8)]#[repr(i64)] / #[repr(C)] pin a payload-free enum's integer width.

Loop hints: #[unroll(N)] and #[vectorize_width(N)]

Statement-level attributes that flow through to LLVM's loop optimizer as !llvm.loop metadata. Apply them to a while, loop, or for. N is a literal in [1, 256].

#[unroll(4)]
while i < n {
    sum = sum + buf[i as usize];
    i = i +% 1;
}

#[vectorize_width(8)]
for i in 0..count {
    out[i as usize] = a[i as usize] * b[i as usize];
}

They are marginal for general code but load-bearing for the tight inner loops the compiler does not vectorize well by default.

#[inline]: inlining control

A function- or method-level attribute, in three forms:

  • #[inline] becomes LLVM inlinehint. Only the optimizer acts on it, so it matters at --release and is a no-op at debug -O0.
  • #[inline(always)] becomes alwaysinline. It inlines even at -O0 and past LLVM's cost threshold, the lever for hot kernels built from small over-threshold helpers.
  • #[inline(never)] becomes noinline. It pins a call boundary for cold paths or code-size control.

These are pure hints with no behavioural change, so reach for them only on measured hot or deliberately cold paths.

Real-time contracts

#[no_alloc], #[no_block], #[bounded_recursion], #[max_stack(N)], and the #[realtime] bundle are compiler-verified contracts, not optimizations. They are documented in full on the Real-time page.

#[naked]: no prologue or epilogue

A function-level attribute for a function whose body is entirely inline assembly and supplies its own ABI handling. It is covered on the Inline assembly page.

Doc comments

/// Returns the square of x.
fn sq(x: i32) -> i32 { return x *% x; }

/// comments are doc comments, and cpc test picks up fenced code blocks inside them as doctests.