=============================================================================== THE NUMBRELLA PROJECT — Syntax Guide =============================================================================== Copyright (C) 2026 Sixten Björling All rights reserved. A syntax reference for the three primary languages used in the Numbrella ecosystem: Python (≥ 3.10), Go, and C/C++ with LLVM/Clang/Clang++. =============================================================================== TABLE OF CONTENTS =============================================================================== PART I — PYTHON (≥ 3.10) PART II — GO PART III — C / C++ (C17 / C++20) with Clang/Clang++ & LLVM =============================================================================== PART I — PYTHON (≥ 3.10) =============================================================================== --- 1.1 Basic Structure ------------------------------------------------ #!/usr/bin/env python3 # -*- coding: utf-8 -*- """Module docstring.""" import sys from pathlib import Path from typing import Any CONSTANT = 42 def main() -> None: """Entry point.""" print("Hello, Numbrella.") if __name__ == "__main__": main() --- 1.2 Variables & Types ---------------------------------------------- x: int = 42 # Integer y: float = 3.14 # Float z: complex = 1 + 2j # Complex name: str = "Numbrella" # String flag: bool = True # Boolean nothing: None = None # None # F-strings (Python ≥ 3.6) s = f"Value: {x}, Name: {name}" # Triple-quoted strings multiline = """Line 1 Line 2""" --- 1.3 Collections ---------------------------------------------------- # List (mutable, ordered) items: list[int] = [1, 2, 3] items.append(4) items.pop() first = items[0] # Tuple (immutable, ordered) coords: tuple[int, int] = (10, 20) x, y = coords # Unpacking # Set (mutable, unordered, unique) tags: set[str] = {"audio", "dsp"} tags.add("midi") # Dictionary (mutable, key-value) config: dict[str, Any] = {"host": "localhost", "port": 8080} config["debug"] = True value = config.get("missing", "default") # Comprehensions squares = [n ** 2 for n in range(10) if n % 2 == 0] mapping = {k: k.upper() for k in ["a", "b", "c"]} --- 1.4 Control Flow --------------------------------------------------- # If / elif / else if x > 0: result = "positive" elif x < 0: result = "negative" else: result = "zero" # Match / case (Python ≥ 3.10) match value: case 0: print("Zero") case 1 | 2: print("One or two") case str(s): print(f"String: {s}") case [first, *rest]: print(f"List starting with {first}") case {"type": "audio", "rate": r}: print(f"Audio at {r} Hz") case _: print("Unknown") # While while condition: do_work() if done: break # For for item in items: process(item) for i, item in enumerate(items): print(f"{i}: {item}") for key, val in config.items(): print(f"{key} = {val}") --- 1.5 Functions ------------------------------------------------------- def add(a: int, b: int) -> int: """Add two integers.""" return a + b # Default arguments def greet(name: str = "World") -> str: return f"Hello, {name}." # Variadic arguments def log(*messages: str, **kwargs: Any) -> None: level = kwargs.get("level", "INFO") for msg in messages: print(f"[{level}] {msg}") # Lambda square = lambda n: n * n # Decorator from functools import wraps def timer(func): @wraps(func) def wrapper(*args, **kwargs): import time start = time.perf_counter() result = func(*args, **kwargs) elapsed = time.perf_counter() - start print(f"{func.__name__} took {elapsed:.4f}s") return result return wrapper @timer def heavy_computation() -> int: return sum(range(1_000_000)) --- 1.6 Classes --------------------------------------------------------- from dataclasses import dataclass @dataclass class AudioClip: path: str sample_rate: int = 44100 channels: int = 2 def duration_ms(self) -> float: """Read from file and compute duration.""" ... # Traditional class class Buffer: def __init__(self, size: int) -> None: self._size = size self._data = bytearray(size) def __len__(self) -> int: return self._size def __getitem__(self, index: int) -> int: return self._data[index] def __enter__(self): return self def __exit__(self, *args): self._data.clear() --- 1.7 Exceptions ------------------------------------------------------ try: risky_operation() except ValueError as e: print(f"Bad value: {e}") except (IOError, OSError): print("I/O failure") else: print("No exception raised") # Runs only on success finally: cleanup() # Always runs # Raise raise RuntimeError("Something went wrong") # Custom exception class NumbrellaError(Exception): """Base exception for Numbrella.""" --- 1.8 Context Managers ------------------------------------------------ with open("file.txt", "r") as f: data = f.read() from contextlib import contextmanager @contextmanager def temporary_path(base: Path): path = base / "temp" path.mkdir(exist_ok=True) try: yield path finally: import shutil shutil.rmtree(path) --- 1.9 Async / Await --------------------------------------------------- import asyncio async def fetch_data(url: str) -> str: async with aiohttp.ClientSession() as session: async with session.get(url) as resp: return await resp.text() async def main() -> None: tasks = [fetch_data(u) for u in urls] results = await asyncio.gather(*tasks) asyncio.run(main()) --- 1.10 Modules & Packages ---------------------------------------------- # Relative imports (inside a package) from . import sibling from .sibling import SomeClass from ..parent_pkg import util # Conditional import try: import orjson as json except ImportError: import json --- 1.11 Type Hints (Advanced) ------------------------------------------- from typing import Generic, TypeVar, Protocol, Literal, Final T = TypeVar("T") class Stack(Generic[T]): def push(self, item: T) -> None: ... def pop(self) -> T: ... class Renderable(Protocol): def render(self) -> str: ... Mode = Literal["read", "write", "append"] MAX_CONNECTIONS: Final = 256 =============================================================================== PART II — GO =============================================================================== --- 2.1 Basic Structure ------------------------------------------------ // +build !wasm ← build constraint (old) //go:build !wasm ← build constraint (Go ≥ 1.17) package main import ( "fmt" "os" ) func main() { fmt.Println("Hello, Numbrella.") os.Exit(0) } --- 2.2 Variables & Types ---------------------------------------------- var name string = "Numbrella" var version = "0.1.0" // Type inferred var x, y int = 10, 20 // Multiple // Short declaration (inside functions only) count := 0 message := fmt.Sprintf("Count: %d", count) // Blanks _, err := doThing() // Constants const MaxRetries = 3 const ( StatusOK = 200 StatusError = 500 ) // Iota enumerator const ( LevelDebug = iota // 0 LevelInfo // 1 LevelWarn // 2 LevelError // 3 ) // Basic types var ( i int = 42 u uint = 100 f64 float64 = 3.1415 f32 float32 = 2.718 b bool = true s string = "hello" r rune = '✓' // Unicode code point (int32) by byte = 255 // uint8 ) --- 2.3 Composite Types ------------------------------------------------ // Array (fixed size, value type) var arr [4]int = [4]int{1, 2, 3, 4} arr[0] = 10 // Slice (dynamic, reference type) items := []int{1, 2, 3} items = append(items, 4, 5) sub := items[1:3] // [2, 3] copied := make([]int, len(items)) copy(copied, items) // Map config := map[string]any{ "host": "localhost", "port": 8080, } config["debug"] = true val, ok := config["missing"] // ok == false if key absent delete(config, "debug") // Struct type AudioClip struct { Path string SampleRate int Channels int _ struct{} // Prevent unkeyed literals } clip := AudioClip{ Path: "/assets/sound.wav", SampleRate: 44100, Channels: 2, } // Pointer ptr := &clip ptr.SampleRate = 48000 // Auto-dereferenced // Interface type Renderer interface { Render() string } func RenderAll(renderers []Renderer) { for _, r := range renderers { fmt.Println(r.Render()) } } --- 2.4 Control Flow --------------------------------------------------- // If (with optional init statement) if val, ok := config["port"]; ok { fmt.Printf("Port: %v\n", val) } else if cfg := loadDefault(); cfg != nil { fmt.Println("Using defaults") } else { fmt.Println("No config available") } // Switch (no fallthrough by default) switch level := getLevel(); level { case LevelDebug: fmt.Println("Debug") case LevelInfo, LevelWarn: // Multiple cases fmt.Println("Info/Warn") default: fmt.Printf("Unknown: %d\n", level) } // Switch without expression = if/else chain switch { case x < 0: fmt.Println("negative") case x == 0: fmt.Println("zero") default: fmt.Println("positive") } // Type switch switch v := data.(type) { case string: fmt.Printf("string: %s\n", v) case int: fmt.Printf("int: %d\n", v) case nil: fmt.Println("nil") } // For (Go's only loop construct) for i := 0; i < 10; i++ { // C-style ... } for condition { // While ... } for { // Infinite if done() { break } } for idx, item := range items { // Range over slice ... } for key, val := range config { // Range over map ... } --- 2.5 Functions ------------------------------------------------------- func add(a, b int) int { return a + b } // Multiple return values func divide(a, b float64) (float64, error) { if b == 0 { return 0, fmt.Errorf("division by zero") } return a / b, nil } // Named return values (naked return) func parse(s string) (result int, err error) { result, err = strconv.Atoi(s) return // Naked return } // Variadic func log(level string, messages ...string) { for _, msg := range messages { fmt.Printf("[%s] %s\n", level, msg) } } // Defer (LIFO, runs on function exit) func readFile(path string) ([]byte, error) { f, err := os.Open(path) if err != nil { return nil, err } defer f.Close() return io.ReadAll(f) } // Closures counter := func() func() int { n := 0 return func() int { n++ return n } }() --- 2.6 Methods & Interfaces ------------------------------------------- type Buffer struct { data []byte } // Value receiver (read-only, copied) func (b Buffer) Len() int { return len(b.data) } // Pointer receiver (can mutate) func (b *Buffer) Write(p []byte) (int, error) { b.data = append(b.data, p...) return len(p), nil } // Interface compliance is implicit (structural typing) var w io.Writer = &Buffer{} // Interface composition type ReadWriteCloser interface { io.Reader io.Writer io.Closer } // Empty interface = any type var anything any = 42 // (any is an alias for interface{} in Go ≥ 1.18) --- 2.7 Generics (Go ≥ 1.18) -------------------------------------------- // Generic function func Map[T, U any](items []T, fn func(T) U) []U { result := make([]U, len(items)) for i, item := range items { result[i] = fn(item) } return result } // Generic type with constraint type Number interface { ~int | ~int64 | ~float64 } func Sum[N Number](values []N) N { var total N for _, v := range values { total += v } return total } // Generic struct type Stack[T any] struct { items []T } func (s *Stack[T]) Push(item T) { s.items = append(s.items, item) } func (s *Stack[T]) Pop() T { item := s.items[len(s.items)-1] s.items = s.items[:len(s.items)-1] return item } --- 2.8 Goroutines & Channels ------------------------------------------ // Goroutine go func() { doWork() }() // Channel (unbuffered) ch := make(chan int) go func() { ch <- 42 }() val := <-ch // Buffered channel ch := make(chan string, 10) // Select (multiplex channels) select { case msg := <-ch: fmt.Println(msg) case ch2 <- data: fmt.Println("sent") case <-time.After(5 * time.Second): fmt.Println("timeout") default: fmt.Println("no activity") } // Directional channels func producer(out chan<- int) { out <- 1 } func consumer(in <-chan int) { _ = <-in } // Close + range close(ch) for item := range ch { ... } // sync.WaitGroup var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go func(n int) { defer wg.Done() process(n) }(i) } wg.Wait() --- 2.9 Error Handling ------------------------------------------------- // Sentinel errors if errors.Is(err, io.EOF) { ... } // Error wrapping (Go ≥ 1.13) if err != nil { return fmt.Errorf("open config: %w", err) } var configErr *ConfigError if errors.As(err, &configErr) { ... } --- 2.10 Embedding ------------------------------------------------------- type Logger struct{} func (l Logger) Log(msg string) { fmt.Println(msg) } type Service struct { Logger // Embedding → Service.Log() promoted Name string } // Interface embedding type FileSystem interface { fs.FS fs.ReadDirFS } --- 2.11 Package Layout -------------------------------------------------- myservice/ ├── main.go // package main ├── internal/ // Not importable outside the module │ ├── db/ │ └── auth/ ├── pkg/ // Public API (consumable by other modules) │ └── client/ ├── cmd/ // Sub-commands │ ├── serve/ │ └── migrate/ ├── go.mod └── go.sum --- 2.12 cgo (C Interop) ------------------------------------------------- /* #cgo CFLAGS: -I${SRCDIR}/../../Libraries #cgo LDFLAGS: -L${SRCDIR}/../../Libraries/FilesLib -lFilesLib #include "FilesLib/header.h" #include */ import "C" import "unsafe" func CallC() { cs := C.CString("data from Go") defer C.free(unsafe.Pointer(cs)) C.process_data(cs) } =============================================================================== PART III — C / C++ (C17 / C++20) WITH CLANG/CLANG++ & LLVM =============================================================================== --- 3.1 Compiler Invocation (Clang / Clang++) -------------------------- # C (C17) clang -std=c17 -Wall -Wextra -Wpedantic -O2 -c source.c -o source.o # C++ (C++20) clang++ -std=c++20 -Wall -Wextra -Wpedantic -O2 -c source.cpp -o source.o # Linking clang++ source.o -lSDL3 -lSDL3_image -o myapp # Full build pipeline clang++ -std=c++20 -O2 main.cpp app.cpp -o app # LLVM IR output (intermediate representation) clang++ -std=c++20 -S -emit-llvm source.cpp -o source.ll # LLVM bitcode clang++ -std=c++20 -c -emit-llvm source.cpp -o source.bc # Assembly output clang++ -std=c++20 -S source.cpp -o source.s # Preprocessor output clang++ -std=c++20 -E source.cpp -o source.i # Sanitizers clang++ -std=c++20 -fsanitize=address -g source.cpp # AddressSanitizer clang++ -std=c++20 -fsanitize=undefined -g source.cpp # UBSan clang++ -std=c++20 -fsanitize=memory -g source.cpp # MemorySanitizer # LTO (Link-Time Optimization) clang++ -std=c++20 -flto=thin -O2 source.cpp -o app # ThinLTO clang++ -std=c++20 -flto=full -O2 source.cpp -o app # Full LTO # Profiling clang++ -std=c++20 -fprofile-instr-generate source.cpp -o app ./app # Produces default.profraw llvm-profdata merge default.profraw -o default.profdata clang++ -std=c++20 -fprofile-instr-use=default.profdata -O2 source.cpp # Modules (C++20) clang++ -std=c++20 -fmodules -fbuiltin-module-map source.cpp --- 3.2 Basic Structure ------------------------------------------------- // ===== C ===== #include #include "mylib.h" #define BUFFER_SIZE 256 int main(int argc, char *argv[]) { printf("Hello, Numbrella.\n"); return 0; } // ===== C++ ===== #include // C++23; use or for C++20 #include "mylib.h" constexpr size_t BUFFER_SIZE = 256; auto main(int argc, char *argv[]) -> int { std::println("Hello, Numbrella."); return 0; } --- 3.3 Preprocessor (C / C++ Shared) ----------------------------------- // Include guards (C; prefer #pragma once in this project) #ifndef MYLIB_H #define MYLIB_H // ... declarations ... #endif // #pragma once (C / C++, supported by all modern compilers) #pragma once // Conditional compilation #ifdef _WIN32 #define PLATFORM "windows" #elif defined(__APPLE__) #define PLATFORM "macos" #elif defined(__linux__) #define PLATFORM "linux" #endif // Macros #define SQUARE(x) ((x) * (x)) #define STRINGIFY(s) #s #define CONCAT(a, b) a ## b // Diagnostic pragmas (Clang/GCC) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-variable" int unused = 0; #pragma clang diagnostic pop --- 3.4 C Syntax (C17) -------------------------------------------------- // ---- Types ---- _Bool flag = 1; // Boolean (stdbool.h → bool) char ch = 'A'; int n = 42; long ln = 1000000L; long long lln = 99999999999LL; float f = 3.14f; double d = 2.7182818; size_t sz = sizeof(int); // Fixed-width (stdint.h) #include int8_t i8 = -128; uint32_t u32 = 0xDEADBEEF; // ---- Arrays ---- int arr[4] = {1, 2, 3, 4}; int arr2[] = {1, 2, 3}; // Size deduced: 3 int matrix[2][3] = {{1,2,3}, {4,5,6}}; // ---- Strings ---- char str[] = "Numbrella"; // Mutable const char *msg = "immutable"; // String literal // ---- Structs ---- struct Point { int x; int y; }; struct Point p = {.x = 10, .y = 20}; // Designated initializer (C99) // Typedef typedef struct { float real; float imag; } Complex; // ---- Unions ---- union Value { int i; float f; char c; }; // ---- Enums ---- enum Status { STATUS_OK = 200, STATUS_NOT_FOUND = 404 }; // ---- Pointers ---- int a = 42; int *p = &a; *p = 100; void *vp = p; // Void pointer (type-erased) int *ip = (int *)vp; // Cast back // Function pointer typedef int (*operation)(int, int); int add(int a, int b) { return a + b; } operation op = add; int result = op(3, 4); // result == 7 // ---- Dynamic Allocation ---- int *data = malloc(100 * sizeof(int)); if (data == NULL) { /* handle */ } free(data); // ---- Control Flow ---- if (x > 0) { ... } else if (x < 0) { ... } else { ... } switch (n) { case 0: handle_zero(); break; // Fallthrough only with explicit break case 1: case 2: handle_one_or_two(); break; default: handle_other(); } for (int i = 0; i < 10; i++) { ... } while (condition) { ... } do { ... } while (condition); // ---- C11/C17 Features ---- // _Generic (type-generic macro) #define ABS(x) _Generic((x), \ int: abs, \ long: labs, \ float: fabsf \ )(x) // _Alignas / _Alignof (C11) _Alignas(16) char aligned_buffer[64]; // _Static_assert (C11) _Static_assert(sizeof(int) >= 4, "int must be at least 4 bytes"); // _Noreturn (C11) _Noreturn void fatal_error(const char *msg); // _Thread_local (C11) _Thread_local int thread_counter = 0; --- 3.5 C++ Syntax (C++20) ---------------------------------------------- // ---- auto & Type Deduction ---- auto x = 42; // int auto y = 3.14; // double auto z = std::vector{1, 2, 3}; // std::vector // ---- constexpr / consteval / constinit ---- constexpr int factorial(int n) { return n <= 1 ? 1 : n * factorial(n - 1); } constexpr int f5 = factorial(5); // Computed at compile time consteval int square(int n) { // C++20: must be compile-time return n * n; } constinit static int counter = 0; // C++20: zero-init at compile time, mutable // ---- Initialization (Uniform / Brace) ---- int a{42}; std::vector v{1, 2, 3, 4}; struct Point { int x; int y; }; Point p{.x = 10, .y = 20}; // Designated initializer (C++20) // ---- References ---- int original = 10; int& ref = original; // L-value reference int&& rref = 42; // R-value reference // ---- Range-based for ---- for (const auto& item : v) { std::println("{}", item); } // ---- Lambdas ---- auto square = [](int n) -> int { return n * n; }; // Capture by value, mutable auto counter = [count = 0]() mutable { return ++count; }; // Capture by reference int total = 0; std::for_each(v.begin(), v.end(), [&total](int n) { total += n; }); // Generic lambda (C++14) auto generic = [](const auto& a, const auto& b) { return a + b; }; // Template lambda (C++20) auto templ = [](const std::vector& vec) -> size_t { return vec.size(); }; // ---- Classes ---- class AudioClip { public: AudioClip(std::string path, int rate = 44100) : m_path(std::move(path)), m_sampleRate(rate) {} auto duration() const -> std::chrono::milliseconds; // Defaulted / deleted AudioClip(const AudioClip&) = default; AudioClip& operator=(const AudioClip&) = delete; // Spaceship operator (C++20) auto operator<=>(const AudioClip&) const = default; private: std::string m_path; int m_sampleRate; }; // ---- Inheritance & Virtual ---- class Shape { public: virtual ~Shape() = default; virtual auto area() const -> double = 0; // Pure virtual }; class Circle final : public Shape { public: explicit Circle(double r) : m_radius(r) {} auto area() const -> double override { return 3.14159 * m_radius * m_radius; } private: double m_radius; }; // ---- Templates ---- template concept Numeric = std::is_arithmetic_v; // C++20 concept template [[nodiscard]] auto sum(const std::vector& values) -> T { T total{}; for (const auto& v : values) total += v; return total; } // Variadic templates template void log(Args&&... args) { (std::println("{}", std::forward(args)), ...); // Fold expression (C++17) } // Template specialization template struct TypeName { static const char* get() { return "unknown"; } }; template <> struct TypeName { static const char* get() { return "int"; } }; template <> struct TypeName { static const char* get() { return "double"; } }; // ---- Modules (C++20) ---- // mymodule.ixx / mymodule.cppm export module mymodule; export auto greet() -> std::string { return "Hello from module"; } // Consumer: import mymodule; // ---- Coroutines (C++20) ---- #include #include // std::generator (C++23; implement manually for C++20) // ---- Ranges (C++20) ---- #include auto even_squares(const std::vector& v) { return v | std::views::filter([](int n) { return n % 2 == 0; }) | std::views::transform([](int n) { return n * n; }); } // ---- std::format / std::print (C++20/23) ---- #include auto msg = std::format("Value: {}, Name: {}", 42, "Numbrella"); std::print("Hello, {}.\n", "World"); // ---- Span (C++20) ---- void process(std::span data) { for (int n : data) { ... } } std::vector v{1,2,3}; process(v); // Works with vector, array, C-array // ---- Expected (C++23; or tl::expected / boost::outcome for C++20) ---- #include // C++23 auto divide(double a, double b) -> std::expected { if (b == 0) return std::unexpected("division by zero"); return a / b; } // ---- Attributes ---- [[nodiscard]] int important_result(); // Warn if return value discarded [[maybe_unused]] int x = 0; // Suppress unused warning [[likely]] if (fast_path) { ... } // Branch prediction hint (C++20) [[unlikely]] if (error_path) { ... } // Branch prediction hint (C++20) [[noreturn]] void fatal(); // Function never returns // ---- Three-way comparison (C++20) ---- struct Version { int major, minor, patch; auto operator<=>(const Version&) const = default; // auto-generates ==, !=, <, <=, >, >= }; --- 3.6 STL Quick Reference (C++20) ------------------------------------ // Containers #include // Dynamic array #include // Fixed-size array #include // String (std::string) #include // Non-owning string view #include // Ordered key-value (red-black tree) #include // Hash map #include // Ordered set #include // Hash set #include // Double-ended queue #include // Doubly-linked list #include // Singly-linked list #include // LIFO #include // FIFO #include // Heap #include // Non-owning view of contiguous data (C++20) #include // Maybe value #include // Type-safe union #include // Type-erased value #include // Heterogeneous tuple #include // Bit array // Algorithms #include // sort, find, copy, transform, etc. #include // accumulate, iota, gcd, lcm #include // Range adaptors (C++20) // Utilities #include // unique_ptr, shared_ptr, make_unique, make_shared #include // Time utilities #include // Threading #include // Mutex, lock_guard, scoped_lock #include // File system operations #include // std::function, std::bind // I/O #include // cin, cout, cerr #include // File I/O #include // String streams #include // std::print, std::println (C++23) #include // std::format (C++20) --- 3.7 Smart Pointers & RAII ------------------------------------------- // Unique ownership auto p1 = std::make_unique("sound.wav"); auto p2 = std::move(p1); // Transfer ownership; p1 == nullptr // Shared ownership auto s1 = std::make_shared(100); auto s2 = s1; // Reference count = 2 // Weak reference (breaks cycles) std::weak_ptr weak = s1; if (auto locked = weak.lock()) { locked->use(); } // RAII guard { std::lock_guard lock(m_mutex); // Auto-locks, auto-unlocks shared_data.modify(); } // Custom deleter auto file = std::unique_ptr( fopen("data.bin", "rb"), fclose ); // Scope guard (manual implementation or library) template class ScopeGuard { F m_func; bool m_active = true; public: explicit ScopeGuard(F f) : m_func(std::move(f)) {} ~ScopeGuard() { if (m_active) m_func(); } void dismiss() { m_active = false; } ScopeGuard(const ScopeGuard&) = delete; ScopeGuard& operator=(const ScopeGuard&) = delete; ScopeGuard(ScopeGuard&&) = default; ScopeGuard& operator=(ScopeGuard&&) = default; }; // Usage: auto guard = ScopeGuard([] { cleanup(); }); --- 3.8 Threading & Atomics --------------------------------------------- // Threads #include std::thread t([] { doWork(); }); t.join(); // Wait for completion // Or t.detach() for fire-and-forget // Mutex & condition variable std::mutex m; std::condition_variable cv; bool ready = false; // Producer { std::lock_guard lk(m); ready = true; } cv.notify_one(); // Consumer std::unique_lock lk(m); cv.wait(lk, [] { return ready; }); // Wait + check predicate // Atomic #include std::atomic counter{0}; counter.fetch_add(1, std::memory_order_relaxed); // Async / Future #include auto fut = std::async(std::launch::async, [] { return compute(); }); auto result = fut.get(); // Blocks until ready // jthread (C++20: auto-joining thread) std::jthread jt([](std::stop_token token) { while (!token.stop_requested()) { doWork(); } }); // jthread auto-joins on destruction; request_stop() cooperatively stops it // Latch / Barrier (C++20) #include std::latch done{3}; // Wait for 3 countdowns done.count_down(); done.wait(); --- 3.9 Move Semantics -------------------------------------------------- class Buffer { public: Buffer(size_t size) : m_data(std::make_unique(size)), m_size(size) {} // Move constructor Buffer(Buffer&& other) noexcept : m_data(std::move(other.m_data)), m_size(other.m_size) { other.m_size = 0; } // Move assignment Buffer& operator=(Buffer&& other) noexcept { if (this != &other) { m_data = std::move(other.m_data); m_size = other.m_size; other.m_size = 0; } return *this; } // Delete copy (move-only type) Buffer(const Buffer&) = delete; Buffer& operator=(const Buffer&) = delete; private: std::unique_ptr m_data; size_t m_size = 0; }; Buffer create() { Buffer b{1024}; return b; // NRVO / move (compiler-elided or moved) } Buffer sink = create(); // Move or copy elision --- 3.10 LLVM IR Basics -------------------------------------------------- // ---- What is LLVM IR? ---- // LLVM Intermediate Representation is a low-level, platform-independent, // Static Single Assignment (SSA) language used between the Clang frontend // and the LLVM backend optimizer/code-generator. // ---- Generating IR ---- // clang++ -std=c++20 -S -emit-llvm source.cpp -o source.ll (text) // clang++ -std=c++20 -c -emit-llvm source.cpp -o source.bc (bitcode) // ---- Minimal .ll Example (hand-written equivalent of a C function) ---- ; Module-level target triple = "x86_64-unknown-linux-gnu" ; @.str = private unnamed_addr constant [14 x i8] c"Hello, %d!\0A\00" declare i32 @printf(i8*, ...) ; define i32 @main() #0 { ; entry: ; %call = call i32 (i8*, ...) @printf(i8* getelementptr (...), i32 42) ; ret i32 0 ; } // ---- Key LLVM IR Concepts ---- // // SSA (Static Single Assignment): // Every virtual register is assigned exactly once. // %result = add i32 %a, %b ← %result can never be re-assigned. // // Basic Blocks: // A straight-line sequence of instructions ending with a terminator // (br, ret, switch, etc.). Labels mark block entry points. // // PHI Nodes: // Merge SSA values from different predecessor blocks. // %val = phi i32 [ %then_val, %then_block ], [ %else_val, %else_block ] // // Types: // i1, i8, i16, i32, i64 ← Integer types // float, double ← FP types // ptr ← Opaque pointer (LLVM ≥ 15) // [N x T] ← Array // { T1, T2, ... } ← Struct // ← Vector // ---- LLVM Toolchain ---- // // llc — Compile .ll/.bc to native assembly // lli — JIT-execute .ll/.bc directly // opt — LLVM optimizer (run passes on IR) // llvm-link — Link multiple .bc files into one // llvm-dis — Disassemble .bc → .ll (human-readable) // llvm-as — Assemble .ll → .bc // llvm-ar — Archive .bc files // llvm-nm — List symbols in .bc files // llvm-objdump — Dump object information // clang — Frontend (C → IR, C++ → IR, IR → native) // ---- Optimization Pipeline (opt) ---- // opt -O2 input.ll -o output.ll // opt -passes="default" input.ll -o output.ll (new PM syntax) // ---- Linking IR ---- // llvm-link a.bc b.bc -o combined.bc // clang++ combined.bc -o program // ---- LTO with Clang ---- // Compile: clang++ -flto=thin -c a.cpp b.cpp → a.o, b.o (contain bitcode) // Link: clang++ -flto=thin a.o b.o -o program // ---- Writing a simple LLVM pass (skeleton) ---- // #include "llvm/Pass.h" // #include "llvm/IR/Function.h" // struct MyPass : public llvm::FunctionPass { // static char ID; // MyPass() : FunctionPass(ID) {} // bool runOnFunction(Function &F) override { // // Inspect/transform F // return false; // true if modified // } // }; // char MyPass::ID = 0; // static RegisterPass X("mypass", "My Analysis Pass"); // ---- Clang Attributes for LLVM IR Control ---- [[gnu::noinline]] void dont_inline_me(); // Suppress inlining [[gnu::always_inline]] inline void must_inline_me(); __attribute__((optnone)) void debug_me(); // Disable optimization for this function // ---- Clang Builtins for low-level access ---- __builtin_expect(cond, 0); // Branch prediction hint __builtin_prefetch(ptr); // Prefetch hint __builtin_assume(cond); // Optimization assumption __builtin_unreachable(); // Mark unreachable code // ---- Compiler Explorer pattern ---- // https://godbolt.org — paste code, see generated LLVM IR / assembly // Useful flags: -std=c++20 -O2 -march=native --- 3.11 Common Clang Attributes & Pragmas ------------------------------- // ---- Function attributes ---- [[nodiscard]] int compute(); // C++17: warn if result unused [[deprecated("Use newAPI() instead")]] void oldAPI(); [[noreturn]] void fatal_exit(); // ---- Clang-specific attributes ---- __attribute__((constructor)) void on_load(); // Run before main() __attribute__((destructor)) void on_unload(); // Run after main() / atexit __attribute__((used)) void keep_symbol(); // Prevent removal even if unused __attribute__((visibility("default"))) void exported_func(); __attribute__((visibility("hidden"))) void internal_func(); __attribute__((aligned(16))) char buffer[64]; __attribute__((packed)) struct Compact { char a; int b; }; // ---- Compiler barriers ---- asm volatile("" ::: "memory"); // Full compiler barrier __sync_synchronize(); // Full memory fence // ---- SIMD pragmas ---- #pragma clang loop vectorize(enable) for (int i = 0; i < N; i++) { ... } #pragma clang loop unroll(enable) for (int i = 0; i < 4; i++) { ... } =============================================================================== END OF SYNTAX GUIDE ===============================================================================