### Migrate C3 Syntax and Keywords Source: https://c3-lang.org/blog/c3-0-7-0-one-step-closer-to-1-0 Examples of syntax updates for generics, type definitions, optional types, and fault handling in C3 0.7.0. ```c3 // Generics List {int} x; // Keywords alias Foo = int; typedef Bar = int; // Optional types int? a; // Faults faultdef ABC, FOO_FAULT; fault the_err = @catch(foo); // Compound literals (Foo) { 1, 2 }; // Expression blocks do { ... }; // Macros and operators $vaarg[1]; val ||| val2; val &&& val2; val +++ val2; ``` -------------------------------- ### C3 Foreach Loop Examples Source: https://c3-lang.org/language-overview/examples Shows how to use foreach loops in C3 for iterating over slices. The first example iterates and prints the index and value of each element in a float slice. The second example demonstrates modifying elements by reference. Requires the 'io' module. ```c3 // Prints the values in the slice. fn void example_foreach(float[] values) { foreach (index, value : values) { io::printfn("%d: %f", index, value); } } // Updates each value in the slice // by multiplying it by 2. fn void example_foreach_by_ref(float[] values) { foreach (&value : values) { *value *= 2; } } ``` -------------------------------- ### C3 While Loop Examples Source: https://c3-lang.org/language-overview/examples Demonstrates the while loop construct in C3, which functions identically to C. It includes an example of decrementing a counter until it reaches zero and another showing a loop with a pointer declaration. No specific module dependencies are shown for basic usage. ```c3 fn void example_while() { // again exactly the same as C int a = 10; while (a > 0) { a--; } // Declaration while (Point* p = getPoint()) { // .. } } ``` -------------------------------- ### Compile a C3 source file Source: https://c3-lang.org/getting-started/prebuilt-binaries Demonstrates the basic command to invoke the C3 compiler to build a source file. ```shell c3c compile ./hello.c3 ``` -------------------------------- ### Install system C compiler dependencies Source: https://c3-lang.org/getting-started/prebuilt-binaries Commands to install the necessary C compiler and development libraries required for linking C3 programs on various Linux distributions. ```bash # Ubuntu / Debian sudo apt-get install gcc libc6-dev # Fedora / Rocky sudo dnf install gcc # Arch Linux sudo pacman -S gcc # openSUSE sudo zypper install gcc glibc-devel # Alpine Linux sudo apk add gcc musl-dev # Void Linux sudo xbps-install -S gcc ``` -------------------------------- ### Install C3 compiler on Arch Linux Source: https://c3-lang.org/getting-started/prebuilt-binaries Methods for installing the C3 compiler on Arch Linux using AUR helpers or manual build processes. ```shell paru -S c3c-git # or yay -S c3c-git # or aura -A c3c-git ``` ```shell git clone https://aur.archlinux.org/c3c-git.git cd c3c-git makepkg -si ``` -------------------------------- ### Utilize Macros with Immediate and Deferred Evaluation Source: https://c3-lang.org/language-overview/examples Explains the C3 macro system, supporting both immediate evaluation and deferred expression duplication using the #var syntax. Includes examples of macro preconditions for improved error reporting. ```c3 macro foo(a, b) { return a(b); } macro @foo(#a, b, #c) { #c = #a(b) * b; } <* @param x : "value to square" @require types::is_numerical($typeof(x)) : "cannot multiply" *> macro square(x) { return x * x; } ``` -------------------------------- ### Run C3 Executable Source: https://c3-lang.org/getting-started/hello-world Command to run the compiled C3 program. On Unix-like systems, this is typically './hello_world'. On Windows, it would be 'hello_world.exe'. ```bash ./hello_world ``` -------------------------------- ### Implement Function Pointers Source: https://c3-lang.org/language-overview/examples Demonstrates how to define function pointer aliases and assign them to functions for flexible callback implementation. ```C3 alias Callback = fn int(char* text, int value); fn int my_callback(char* text, int value) { return 0; } Callback cb = &my_callback; fn void example_cb() { int result = cb("demo", 123); } ``` -------------------------------- ### C3 Function Definition Source: https://c3-lang.org/getting-started/hello-world An example of defining a function in C3. This snippet shows the basic structure of a function declaration, including the `fn` keyword, return type (`void`), function name (`main`), and an empty parameter list. ```c3 fn void main() {} ``` -------------------------------- ### Defer and Return Example in C3 Source: https://c3-lang.org/implementation-details/specification Demonstrates how 'defer' statements interact with 'return' statements that have expressions. The example shows that the return expression is evaluated before the deferred statements are executed, effectively preserving the original value. ```c3 int a = 0; defer a++; return a; // This is equivalent to int a = 0; int temp = a; a++; return temp; ``` -------------------------------- ### Compile and Run C3 Program with c3c Source: https://c3-lang.org/getting-started/hello-world Command to compile and immediately run a C3 program using `c3c compile-run`. This is a convenient option for quick testing and development. ```bash $ c3c compile-run hello_world.c3 > Program linked to executable 'hello_world'. > Launching hello_world... > Hello, World ``` -------------------------------- ### C3 Generics: Stack Implementation Source: https://c3-lang.org/language-overview/examples Demonstrates generic struct and function declarations in C3 for creating a type-agnostic stack. It includes push, pop, and empty operations, with examples of instantiating the stack for integers and doubles. ```c3 module stack; struct Stack { usz capacity; usz size; Type* elems; } fn void Stack.push(Stack* this, Type element) { if (this.capacity == this.size) { this.capacity = this.capacity ? this.capacity * 2 : 16; this.elems = realloc(this.elems, Type.sizeof * this.capacity); } this.elems[this.size++] = element; } fn Type Stack.pop(Stack* this) { assert(this.size > 0); return this.elems[--this.size]; } fn bool Stack.empty(Stack* this) { return !this.size; } ``` ```c3 alias IntStack = Stack{int}; fn void test() { IntStack stack; stack.push(1); stack.push(2); // Prints pop: 2 io::printfn("pop: %d", stack.pop()); // Prints pop: 1 io::printfn("pop: %d", stack.pop()); Stack {double} dstack; dstack.push(2.3); dstack.push(3.141); dstack.push(1.1235); // Prints pop: 1.1235 io::printfn("pop: %f", dstack.pop()); } ``` -------------------------------- ### C3 Implicit Narrowing Examples Source: https://c3-lang.org/language-rules/conversion Demonstrates implicit narrowing of integer and float types in C3. It shows scenarios where conversions are allowed and where they result in errors due to type width mismatches. The examples illustrate how arithmetic operations involving different numeric types are handled. ```c3 float16 h = 12.0; float f = 13.0; double d = 22.0; char x = 1; short y = -3; int z = 0xFFFFF; ulong w = -0xFFFFFFF; x = x + x; // => Calculated as `x = (char)((int)x + (int)x);`. x = y + x; // => Error. Narrowing is not allowed because short y is wider than char x. h = x * h; // => Calculated as `h = (float16)((float)x * (float)h);`. h = f + x; // => Error. Narrowing is not allowed because float f is wider than float16 h. ``` -------------------------------- ### Hello World in C3 Source: https://c3-lang.org/ A basic example demonstrating the module system, imports, and the main entry point in C3. It uses the standard I/O library to print a string to the console. ```c3 module hello_world; import std::io; fn void main() { io::printn("Hello, world!"); } ``` -------------------------------- ### Capture Manual Backtraces in C3 Source: https://c3-lang.org/misc-advanced/debugging Demonstrates how to import the backtrace module and capture the current call stack as a string for logging purposes. ```c3 import std::os::backtrace; fn void log_stack() { String bt = backtrace::get(tmem)!; io::eprint(bt); } ``` -------------------------------- ### Compile C3 Program using c3c Source: https://c3-lang.org/getting-started/hello-world Command to compile a C3 program file named 'hello_world.c3' using the C3 compiler (`c3c`). This generates an executable file. ```bash c3c compile hello_world.c3 ``` -------------------------------- ### C3 For Loop Examples Source: https://c3-lang.org/language-overview/examples Illustrates the usage of for loops in C3, which are similar to C99. It shows a standard for loop iterating from 0 to 9 and printing each number, as well as an infinite for loop. Requires the 'io' module for printing. ```c3 fn void example_for() { // the for-loop is the same as C99. for (int i = 0; i < 10; i++) { io::printfn("%d", i); } // also equal for (;;) { // .. } } ``` -------------------------------- ### C3 Hello World Program Source: https://c3-lang.org/getting-started/hello-world The traditional 'Hello, World!' program in C3. It imports the 'io' module for printing and defines a main function that prints 'Hello, World!' to the console. ```c3 import std::io; fn void main() { io::printn("Hello, World!"); } ``` -------------------------------- ### Perform Unit Testing in C3 Source: https://c3-lang.org/misc-advanced/debugging Demonstrates the use of the built-in testing framework to validate logic with descriptive failure messages. ```c3 fn void test_math() @test { int x = 10; int y = 20; test::eq(x + y, 40); // Test failed ^^^ ( example.c3:4 ) `30` != `40` } ``` -------------------------------- ### Implement Contracts with Pre- and Postconditions Source: https://c3-lang.org/language-overview/examples Demonstrates the use of contract annotations to define requirements and guarantees for functions. These are optionally compiled into assertions to aid in code optimization and safety. ```c3 <* @param foo : "the number of foos" @require foo > 0, foo < 1000 @return "number of foos x 10" @ensure return < 10000, return > 0 *> fn int test_foo(int foo) { return foo * 10; } <* @param array : "the array to test" @param length : "length of the array" @require length > 0 *> fn int get_last_element(int* array, int length) { return array[length - 1]; } ``` -------------------------------- ### C3 Enum and Switch Statement Examples Source: https://c3-lang.org/language-overview/examples Illustrates the use of enums and switch statements in C3. It covers defining enums, basic switch cases with implicit breaks, explicit breaks, fallthrough using 'nextcase', and scope within cases. Also shows enum reflection properties like .values, .len, .names. Requires the 'io' module. ```c3 enum Height : uint { LOW, MEDIUM, HIGH, } fn void demo_enum(Height h) { switch (h) { case LOW: case MEDIUM: io::printn("Not high"); // Implicit break. case HIGH: io::printn("High"); } // This also works switch (h) { case LOW: case MEDIUM: io::printn("Not high"); // Implicit break. case Height.HIGH: io::printn("High"); } // Completely empty cases are not allowed. switch (h) { case LOW: break; // Explicit break required, since switches can't be empty. case MEDIUM: io::printn("Medium"); case HIGH: break; } // special checking of switching on enum types switch (h) { case LOW: case MEDIUM: case HIGH: break; default: // warning: default label in switch which covers all enumeration value break; } // Using "nextcase" will fallthrough to the next case statement, // and each case statement starts its own scope. switch (h) { case LOW: int a = 1; io::printn("A"); nextcase; case MEDIUM: int a = 2; io::printn("B"); nextcase; case HIGH: // a is not defined here io::printn("C"); } } enum State : uint { START, STOP, } State start = State.values[0]; usz enums = State.elements; // 2 String[] names = State.names; // [ "START", "STOP" ] ``` -------------------------------- ### Implementing Printable interface Source: https://c3-lang.org/generic-programming/anyinterfaces Example of implementing a standard library interface for a custom struct to provide string representation. ```C3 fn String Baz.to_new_string(Baz* baz, Allocator allocator) @dynamic { return string::printf("Baz(%d)", baz.x, allocator: allocator); } ``` -------------------------------- ### Perform Compile Time Reflection and Execution Source: https://c3-lang.org/language-overview/examples Demonstrates how to inspect type metadata at compile time using macros and perform compile-time calculations like recursive functions. ```c3 macro print_fields($Type) { $foreach $field : $Type.membersof: io::printfn("Field %s, offset: %s, size: %s, type: %s", $field.nameof, $field.offsetof, $field.sizeof, $field.typeid.nameof); $endforeach } macro long fib(long $n) { $if $n <= 1: return $n; $else return fib($n - 1) + fib($n - 2); $endif } ``` -------------------------------- ### Define Modules, Functions, and Macros Source: https://c3-lang.org/language-fundamentals/naming Module names must be lowercase. Functions and macros must start with a lowercase letter. ```C3 module foo; fn int anotherFunction() { } macro justDoIt(x) { justDo(x); } ``` -------------------------------- ### Declare Variables and Parameters in C3 Source: https://c3-lang.org/language-fundamentals/naming Shows variable and parameter naming, which must start with a lowercase letter. Global constants are excluded from this rule. ```C3 int theGlobal = 1; fn void foo(int x) { Foo foo = getFoo(x); theGlobal++; } ``` -------------------------------- ### Declare Global Constants and Enum Members Source: https://c3-lang.org/language-fundamentals/naming Global constants and enum members must start with an uppercase letter. This snippet shows both constant declarations and fault definitions. ```C3 const int A_VALUE = 12; enum Baz { VALUE_1, VALUE_2 } faultdef OOPS, LOTS_OF_OOPS; ``` -------------------------------- ### C3 Path Shortening for Imports Source: https://c3-lang.org/getting-started/hello-world Demonstrates path-shortening in C3 imports. It shows both the full import path and the shortened version, highlighting the convention of using the lowest level module name for easier code readability. ```c3 std::io::printn("Hello, World!"); io::printn("Hello, World!"); ``` -------------------------------- ### Define User-Defined Types in C3 Source: https://c3-lang.org/language-fundamentals/naming Demonstrates the declaration of structs, unions, and enums. These types must start with an uppercase letter and include at least one lowercase character. ```C3 struct Foo @cname("foo") { int x; Bar bar; } union Bar { int i; double d; } enum Baz { VALUE_1, VALUE_2 } ``` -------------------------------- ### Manage Static Initializers and Finalizers Source: https://c3-lang.org/language-fundamentals/functions Demonstrates how to run code at program startup and shutdown using @init and @finalizer attributes, including priority configuration. ```C3 fn void run_at_startup() @init { some_function.init(512); } fn void run_at_shutdown() @finalizer { some_thing.shutdown(); } fn void start_world() @init(3000) { io::printn("World"); } fn void start_hello() @init(2000) { io::print("Hello "); } ``` -------------------------------- ### Get Type of Expression with C3 $typeof Source: https://c3-lang.org/generic-programming/compiletime The $typeof function retrieves the type of an expression at compile time without runtime evaluation, ensuring no side effects. This is useful for compile-time type assertions and checks. The example shows how to assert the type of a variable. ```c3 fn void typeof_has_no_side_effects() @test { int minutes_left = 20; $assert($typeof(minutes_left += 10).nameof == "int"); assert(minutes_left == 20); // The state of `minutes_left` above never changes. } ``` -------------------------------- ### Initialize a new C3 project Source: https://c3-lang.org/build-your-project/build-commands Creates a standard C3 project directory structure. Supports templates like 'exe', 'static-lib', and 'dynamic-lib' to scaffold the project. ```shell c3c init [optional path] ``` -------------------------------- ### C3 If Statement Example Source: https://c3-lang.org/language-overview/examples Demonstrates the basic syntax for an if-else conditional statement in C3. It checks if an integer variable 'a' is greater than 0 and executes different code blocks accordingly. No external dependencies are required. ```c3 fn void if_example(int a) { if (a > 0) { // .. } else { // .. } } ``` -------------------------------- ### Formatted Output with io::printfn Source: https://c3-lang.org/language-fundamentals/basic-types-and-values Shows how to use printfn for formatted string output. It supports standard formatting specifiers and demonstrates casting byte arrays to strings. ```c3 import std::io; fn void main() { int a = 1234; ulong b = 0xFFAABBCCDDEEFF; double d = 13.03e-04; char[*] hex = x"4865 6c6c 6f20 776f 726c 6421"; io::printfn("a was: %d", a); io::printfn("b in hex was: %x", b); io::printfn("d in scientific notation was: %e", d); io::printfn("Bytes as string: %s", (String)&hex); } ``` -------------------------------- ### Work with Slices Source: https://c3-lang.org/language-common/arrays Demonstrates how to create slices from fixed arrays and pointers, and how slices interact with other types through implicit conversions. ```C3 fn void test() { int[4] arr = { 1, 2, 3, 4 }; int[4]* ptr = &arr; int[] slice1 = &arr; // Implicit conversion int[] slice2 = ptr; // Implicit conversion int[] slice3 = slice1; // Assign slices from other slices int* int_ptr = slice1; // Assign from slice int[4]* arr_ptr = (int[4]*)slice1; // Cast from slice } ``` -------------------------------- ### Operator Precedence Comparison C vs C3 Source: https://c3-lang.org/language-rules/precedence Examples demonstrating how C3's operator precedence differs from C, specifically regarding bitwise, shift, and relational operators. These examples illustrate why explicit parentheses are often required in C3 to maintain intended logic. ```c3 a + b >> c + d (a + b) >> (c + d) // C (+ - are evaluated before >>) a + (b >> c) + d // C3 (>> is evaluated before + -) a & b == c a & (b == c) // C (bitwise operators are evaluated after relational) (a & b) == c // C3 (bitwise operators are evaluated before relational) a > b == c < d (a > b) == (c < d) // C (< > binds tighter than ==) ((a > b) == c) < d // C3 Error, requires parenthesis! a | b ^ c & d a | ((b ^ c) & d) // C (All bitwise operators have different precedence) ((a | b) ^ c) & d // C3 Error, requires parenthesis! ``` -------------------------------- ### List Initialization with Allocators (C3) Source: https://c3-lang.org/language-common/memory Demonstrates how to initialize a List with different allocators (heap, temp) and manage its memory. Requires the 'mem' or 'tmem' allocator and basic List operations. ```c3 List{int} list; list.init(mem); // "list" will use the heap allocator list.push(1); list.push(42); io::printn(list); // Prints "{ 1, 42 }" list.free(); // Free the memory in the list ``` -------------------------------- ### C3 Array Slicing with Omitted Indices and Lengths Source: https://c3-lang.org/language-common/arrays Shows how to create array slices by omitting start and end indices or slice lengths. Omitting the start index defaults to 0, and omitting the end index defaults to the last element. This provides concise ways to slice entire arrays or from the beginning/to the end. ```c3 fn void test() { int[5] a = { 1, 20, 50, 100, 200 }; int[] b = a[0 .. 4]; int[] c = a[..4]; int[] d = a[0..]; int[] e = a[..]; int[] f = a[0 : 5]; int[] g = a[:5]; } ``` -------------------------------- ### Calling C3 Functions from C Source: https://c3-lang.org/language-common/cinterop Provides an example of how C code can call C3 functions that have been exported. It demonstrates using 'extern' declarations in C for C3 functions and how aliasing with '__attribute__((weak, alias(...)))' can be used to manage function calls. ```c extern int square(int); int foo_square(int) __attribute__ ((weak, alias ("foo__square"))); void test() { // This would call square2 printf("%d\n", square(11)); // This would call square printf("%d\n", foo_square(11)); } ``` -------------------------------- ### Update C3 Contracts and Attributes Source: https://c3-lang.org/blog/c3-0-7-0-one-step-closer-to-1-0 Demonstrates the updated syntax for contracts and attribute declarations in C3 0.7.0. ```c3 // Contracts @require a > b : "a must be greater than b"; @return?; // Attributes alias Foo @public = int; attrdef MyAttribute; ``` -------------------------------- ### Implement Operator Overloading Source: https://c3-lang.org/language-overview/examples Demonstrates how to overload standard operators for custom struct types by defining functions with the @operator attribute. ```c3 struct Vec2 { int x, y; } fn Vec2 Vec2.add(self, Vec2 other) @operator(+) { return { self.x + other.x, self.y + other.y }; } fn Vec2 Vec2.sub(self, Vec2 other) @operator(-) { return { self.x - other.x, self.y - other.y }; } ``` -------------------------------- ### Initialize a new C3 project Source: https://c3-lang.org/getting-started/projects Uses the c3c init command to generate a new project directory structure. The command requires a project name as an argument. ```bash c3c init myc3project ``` -------------------------------- ### Error Handling with @try and @try_catch Source: https://c3-lang.org/blog/c3-0-7-4-released-enhanced-enum-support-and-smarter-error-handling Shows how to use the @try and @try_catch macros to streamline error handling and optional unwrapping, reducing the need for temporary variables when assigning values. ```C3 fn void test2_new() { int f = abc(); while (some_condition()) { if (catch err = @try(f, foo())) { return; } } } fn void update_new() { (void)@try(my_global, foo()); } fn void? test3_new() { while (true) { String s; if (@try_catch(s, next_string(), io::EOF)!) break; use_string(s); } } ``` -------------------------------- ### Define Structs and Unions Source: https://c3-lang.org/language-overview/examples Shows the syntax for defining custom data structures in C3, including enums, named/anonymous sub-structs, and unions. ```C3 alias Callback = fn int(char c); enum Status : int { IDLE, BUSY, DONE, } struct MyData { char* name; Callback open; Callback close; Status status; struct other { int value; int status; } struct { int value; int status; } union { Person* person; Company* company; } union either { int this; bool or; char* that; } } ``` -------------------------------- ### Manage scope-based execution with Defer Source: https://c3-lang.org/language-overview/examples Demonstrates how to use the defer keyword to execute code upon scope exit. Includes advanced usage with conditional execution via 'try' and 'catch' modifiers for error handling. ```C3 fn void test(int x) { defer io::printn(); defer io::print("A"); if (x == 1) return; { defer io::print("B"); if (x == 0) return; } io::print("!"); } fn void? test_error(int x) { defer io::printn(""); defer io::print("A"); defer try io::print("X"); defer catch io::print("B"); defer (catch err) io::printf("%s", err); if (x == 1) return NOT_FOUND~; io::print("!"); } ``` -------------------------------- ### Conditional compilation with $if and $switch Source: https://c3-lang.org/generic-programming/compiletime Examples of using $if and $switch directives to conditionally generate code based on compile-time constant expressions. ```C3 macro @foo($x, #y) { $if $x > 3: #y += $x * $x; $else #y += $x; $endif } macro @bar($x, #y) { $switch $x: $case 1: #y += $x * $x; $default: #y -= $x; $endswitch } ``` -------------------------------- ### Create value-returning macros in C3 Source: https://c3-lang.org/generic-programming/macros Demonstrates how macros can return values, allowing them to function as expressions. It also shows how macros can be composed by calling other macros. ```C3 macro square(x) { return x * x; } macro squarePlusOne(x) { return square(x) + 1; } fn int getTheSquare(int x) { return square(x); } ``` -------------------------------- ### C3 Implicit Widening Examples Source: https://c3-lang.org/language-rules/conversion Illustrates implicit widening conversions in C3, focusing on simple expressions and assignment rules. It highlights valid and invalid scenarios for implicit promotions, particularly in binary operations and assignments. ```c3 int a = ... short b = ... char c = ... long d = a; // Valid - simple expression. int e = (int)(d + (a + b)); // Error int f = (int)(d + ~b); // Valid long g = a + b; // Valid ``` -------------------------------- ### Update C3 Memory Management Source: https://c3-lang.org/blog/c3-0-7-0-one-step-closer-to-1-0 Shows the transition from implicit heap allocation to explicit allocator usage in C3 0.7.0. ```c3 // Old: allocator::temp() / allocator::heap() // New: tmem; mem; // Explicit initialization init(mem); // Thread pool initialization @pool_init(); ``` -------------------------------- ### Any-switch Example in C3 Source: https://c3-lang.org/implementation-details/specification Demonstrates how to use the 'any' type in a switch statement. The switch logic is based on the type field of the 'any' variable. Cases can handle different types, and a default case is provided for unhandled types. ```c3 any a = abc(); switch (a) { case int: int b = *a; // a is int* case float: float z = *a; // a is float* case Bar: Bar f = *a; // a is Bar* default: // a is not unwrapped } ``` -------------------------------- ### Get Enum Names - C3 Source: https://c3-lang.org/generic-programming/reflection Retrieves a slice containing the names of an enum. This function is useful for introspection and debugging purposes. ```c3 enum FooEnum { BAR, BAZ } String[] x = FooEnum.names; // ["BAR", "BAZ"] ``` -------------------------------- ### Implement Runtime Assertions Source: https://c3-lang.org/misc-advanced/debugging Uses the assert macro to validate conditions during runtime, which triggers a panic in Safe Mode if the condition is false. ```c3 assert(divisor != 0, "Cannot divide by zero!"); ``` -------------------------------- ### Initialize Data from Base64 and Hex Literals Source: https://c3-lang.org/language-fundamentals/basic-types-and-values Demonstrates compile-time conversion of Base64 and hexadecimal encoded strings into character arrays. ```c3 char[*] hello_world_base64 = b64"SGVsbG8gV29ybGQh"; char[*] hello_world_hex = x"4865 6c6c 6f20 776f 726c 6421"; ``` -------------------------------- ### Array Initialization and Copying in C and C3 Source: https://c3-lang.org/language-overview/primer Shows the difference in array initialization and copying. C3 allows direct array assignment for trivially copyable arrays, simplifying the process compared to C's manual element-wise copy. ```C int x[3] = ...; int y[3]; for (int i = 0; i < 3; i++) y[i] = x[i]; ``` ```C3 int[3] x = ...; int[3] y = x; ``` -------------------------------- ### Control flow with defer and error handling Source: https://c3-lang.org/faq/allfeatures Examples of using defer for scope cleanup and if-try/if-catch blocks for handling Optional return types. ```c3 defer { /* cleanup code */ } defer try { /* runs on success */ } defer catch { /* runs on fault */ } if (try x = get_result()) { // Handle happy path } else if (catch e = get_result()) { // Handle failure path } ``` -------------------------------- ### Compile and run C3 files Source: https://c3-lang.org/build-your-project/build-commands Compiles the specified C3 source files and immediately executes the resulting binary. This is useful for quick prototyping and testing small snippets. ```shell c3c compile-run ``` -------------------------------- ### Configure C3C_LIB environment variable Source: https://c3-lang.org/getting-started/prebuilt-binaries Sets the C3C_LIB environment variable to point to the standard library location, resolving module lookup errors. ```bash export C3C_LIB=/path/to/c3c/lib ``` ```fish set -gx C3C_LIB /path/to/c3c/lib ``` ```powershell $env:C3C_LIB = "C:\path\to\c3c\lib" ``` -------------------------------- ### Track Memory Allocations with TrackingAllocator Source: https://c3-lang.org/misc-advanced/debugging Wraps a standard allocator to monitor memory usage and generate reports to identify potential memory leaks. ```c3 fn void main() { TrackingAllocator tracker; tracker.init(mem); // Wrap the default 'mem' allocator defer tracker.free(); Allocator a = &tracker; // Use 'allocator::new' to pass a specific allocator: int* p = allocator::new(a, int); // If not freed, tracker.print_report() will show any leaks. tracker.print_report(); } ``` -------------------------------- ### Get Enum Values - C3 Source: https://c3-lang.org/generic-programming/reflection Returns a slice containing the values of an enum. This function allows iteration over enum members and retrieval of their names. ```c3 enum FooEnum { BAR, BAZ } String x = FooEnum.values[1].nameof; // "BAR" ``` -------------------------------- ### Vector Swizzle Initialization Source: https://c3-lang.org/blog/jingle-bells%2C-c3-0-7-8- Shows how to initialize vector components using named swizzle syntax instead of array-style indexing. This requires a consecutive, gapless range of components. ```C3 float[<3>] x = { .xy = 1.2, .z = 3.3 }; // Same as float[<3>] x = { [0..1] = 1.2, [2] = 3.2 }; ``` -------------------------------- ### Vector ABI and SIMD usage in C3 Source: https://c3-lang.org/blog/c3-language-at-0-7-7-vector-abi%2C-riscv-improvements-and-more Demonstrates the transition from manual struct-based vector handling to native array-based vector ABI, allowing for direct SIMD operations and improved compatibility with C libraries. ```C3 // Pre 0.7.7 union Vec3 { struct { float x, y, z; } float[3] arr; } extern fn void draw_image(Image* image, Vec3 pos); fn void update() { ... float[<3>] speed = ball.speed.arr; float[<3>] position = ball.position.arr; ball.position = (position + speed); } // 0.7.7+ alias Vec3 = float[<3>]; extern fn void draw_image(Image* image, Vec3 pos); fn void update() { ... ball.position += ball.speed; } ``` -------------------------------- ### Get Parent Type - C3 Source: https://c3-lang.org/generic-programming/reflection Returns the typeid of the parent type for bitstruct and struct types. This is useful for understanding type hierarchies and relationships. ```c3 struct Foo { int a; } struct Bar { inline Foo f; } String x = Bar.parentof.nameof; // "Foo" ``` -------------------------------- ### Initialize Arrays with Explicit and Implicit Sizing Source: https://c3-lang.org/language-fundamentals/basic-types-and-values Demonstrates how to declare arrays using fixed sizes or the wildcard operator to infer length from the initializer list. ```c3 int[3] abc = { 1, 2, 3 }; // Explicit int[3] int[*] bcd = { 1, 2, 3 }; // Implicit int[3] ``` -------------------------------- ### Define Struct Methods with Dot Syntax Source: https://c3-lang.org/language-overview/examples Shows how to namespace functions with struct types to enable object-oriented style method calls using the dot operator. ```c3 struct Foo { int i; } fn void Foo.next(Foo* this) { if (this) this.i++; } fn void test() { Foo foo = { 2 }; foo.next(); foo.next(); io::printfn("%d", foo.i); } ``` -------------------------------- ### C3 Instantiating Generic Types and Functions Source: https://c3-lang.org/generic-programming/generics Demonstrates how to use generic types and functions in C3 by creating aliases or invoking them directly with specific type and constant arguments. This example shows instantiation with different types. ```c3 import foo_test; alias FooFloat = Foo {float, double}; alias test_float = foo_test::test {float, double}; ... FooFloat f; Foo{int, double} g; ... test_float(1.0, &f); foo_test::test{int, double} (1.0, &g); ``` -------------------------------- ### Get Type ID - C3 Source: https://c3-lang.org/generic-programming/reflection Returns the typeid for a given type. `alias`es will return the typeid of the underlying type. The typeid size is the same as that of an `iptr`. ```c3 typeid x = Foo.typeid; ``` -------------------------------- ### Get Return Type - C3 Source: https://c3-lang.org/generic-programming/reflection Returns the typeid of the return type for function types. This allows inspection of the return type of a function at compile time. ```c3 alias TestFunc = fn int(int, double); String s = TestFunc.returns.nameof; // "int" ``` -------------------------------- ### Get Array Length and Enum Member Count Source: https://c3-lang.org/generic-programming/reflection Uses the len property to determine the size of an array type or the number of constants defined in an enum. ```C3 enum Foo { BAR, BAZ } usz len = int[4].len; // 4 int foo_values = Foo.len; // 2 ```