blob fcf07eb6 (401794B) - Raw
1 <!doctype html> 2 <html lang="en"> 3 <head> 4 <meta charset="utf-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <title>Documentation - The Zig Programming Language</title> 7 <link rel="icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAgklEQVR4AWMYWuD7EllJIM4G4g4g5oIJ/odhOJ8wToOxSTXgNxDHoeiBMfA4+wGShjyYOCkG/IGqWQziEzYAoUAeiF9D5U+DxEg14DRU7jWIT5IBIOdCxf+A+CQZAAoopEB7QJwBCBwHiip8UYmRdrAlDpIMgApwQZNnNii5Dq0MBgCxxycBnwEd+wAAAABJRU5ErkJggg=="/> 8 <style> 9 body{ 10 font-family: system-ui, -apple-system, Roboto, "Segoe UI", sans-serif; 11 margin: 0; 12 } 13 a:not(:hover) { 14 text-decoration: none; 15 } 16 table, th, td { 17 border-collapse: collapse; 18 border: 1px solid grey; 19 } 20 th, td { 21 padding: 0.1em; 22 } 23 .t0_1, .t37, .t37_1 { 24 font-weight: bold; 25 } 26 .t2_0 { 27 color: grey; 28 } 29 .t31_1 { 30 color: red; 31 } 32 .t32_1 { 33 color: green; 34 } 35 .t36_1 { 36 color: #0086b3; 37 } 38 .file { 39 text-decoration: underline; 40 } 41 pre,code { 42 font-size: 12pt; 43 } 44 pre > code { 45 display: block; 46 overflow: auto; 47 padding: 0.5em; 48 color: #333; 49 background: #f8f8f8; 50 } 51 .table-wrapper { 52 width: 100%; 53 overflow-y: auto; 54 } 55 56 .tok-kw { 57 color: #333; 58 font-weight: bold; 59 } 60 .tok-str { 61 color: #d14; 62 } 63 .tok-builtin { 64 color: #0086b3; 65 } 66 .tok-comment { 67 color: #777; 68 font-style: italic; 69 } 70 .tok-fn { 71 color: #900; 72 font-weight: bold; 73 } 74 .tok-null { 75 color: #008080; 76 } 77 .tok-number { 78 color: #008080; 79 } 80 .tok-type { 81 color: #458; 82 font-weight: bold; 83 } 84 85 #main-wrapper { 86 display: flex; 87 flex-direction: column; 88 } 89 90 #contents-wrapper { 91 flex-grow: 1; 92 padding: 0 2em; 93 } 94 95 #contents { 96 max-width: 60em; 97 margin: auto; 98 } 99 100 #toc { 101 padding: 0 1em; 102 } 103 104 @media screen and (min-width: 1025px) { 105 #main-wrapper { 106 flex-direction: row; 107 } 108 #toc { 109 height: 100vh; 110 position: sticky; 111 top: 0; 112 } 113 #contents-wrapper, #toc { 114 overflow: auto; 115 } 116 } 117 118 h1 a, h2 a, h3 a, h4 a, h5 a { 119 text-decoration: none; 120 color: #333; 121 } 122 123 a.hdr { 124 visibility: hidden; 125 } 126 h1:hover > a.hdr, h2:hover > a.hdr, h3:hover > a.hdr, h4:hover > a.hdr, h5:hover > a.hdr { 127 visibility: visible; 128 } 129 130 @media (prefers-color-scheme: dark) { 131 body{ 132 background-color:#111; 133 color: #bbb; 134 } 135 a { 136 color: #f7a31d; 137 } 138 table, th, td { 139 border-color: grey; 140 } 141 .t2_0 { 142 color: grey; 143 } 144 .t31_1 { 145 color: red; 146 } 147 .t32_1 { 148 color: green; 149 } 150 .t36_1 { 151 color: #0086b3; 152 } 153 pre > code { 154 color: #ccc; 155 background: #222; 156 } 157 .tok-kw { 158 color: #eee; 159 } 160 .tok-str { 161 color: #2e5; 162 } 163 .tok-builtin { 164 color: #ff894c; 165 } 166 .tok-comment { 167 color: #aa7; 168 } 169 .tok-fn { 170 color: #e33; 171 } 172 .tok-null { 173 color: #ff8080; 174 } 175 .tok-number { 176 color: #ff8080; 177 } 178 .tok-type { 179 color: #68f; 180 } 181 h1 a, h2 a, h3 a, h4 a, h5 a { 182 color: #aaa; 183 } 184 } 185 </style> 186 </head> 187 <body> 188 <div id="main-wrapper"> 189 <div id="toc"> 190 <a href="https://ziglang.org/documentation/0.1.1/">0.1.1</a> | 191 <a href="https://ziglang.org/documentation/0.2.0/">0.2.0</a> | 192 <a href="https://ziglang.org/documentation/0.3.0/">0.3.0</a> | 193 <a href="https://ziglang.org/documentation/0.4.0/">0.4.0</a> | 194 <a href="https://ziglang.org/documentation/0.5.0/">0.5.0</a> | 195 <a href="https://ziglang.org/documentation/0.6.0/">0.6.0</a> | 196 <a href="https://ziglang.org/documentation/0.7.1/">0.7.1</a> | 197 <a href="https://ziglang.org/documentation/0.8.0/">0.8.0</a> | 198 master 199 <h1>Contents</h1> 200 {#nav#} 201 </div> 202 <div id="contents-wrapper"><div id="contents"> 203 {#header_open|Introduction#} 204 <p> 205 Zig is a general-purpose programming language and toolchain for maintaining 206 <strong>robust</strong>, <strong>optimal</strong>, and <strong>reusable</strong> software. 207 </p> 208 <ul> 209 <li><strong>Robust</strong> - behavior is correct even for edge cases such as out of memory.</li> 210 <li><strong>Optimal</strong> - write programs the best way they can behave and perform.</li> 211 <li><strong>Reusable</strong> - the same code works in many environments which have different 212 constraints.</li> 213 <li><strong>Maintainable</strong> - precisely communicate intent to the compiler and 214 other programmers. The language imposes a low overhead to reading code and is 215 resilient to changing requirements and environments.</li> 216 </ul> 217 <p> 218 Often the most efficient way to learn something new is to see examples, so 219 this documentation shows how to use each of Zig's features. It is 220 all on one page so you can search with your browser's search tool. 221 </p> 222 <p> 223 The code samples in this document are compiled and tested as part of the main test suite of Zig. 224 </p> 225 <p> 226 This HTML document depends on no external files, so you can use it offline. 227 </p> 228 <p> 229 <a href="https://github.com/ziglang/zig/wiki/FAQ#where-is-the-documentation-for-the-zig-standard-library">Where is the documentation for the Zig standard library?</a> 230 </p> 231 {#header_close#} 232 233 {#header_open|Hello World#} 234 235 {#code_begin|exe|hello#} 236 const std = @import("std"); 237 238 pub fn main() !void { 239 const stdout = std.io.getStdOut().writer(); 240 try stdout.print("Hello, {s}!\n", .{"world"}); 241 } 242 {#code_end#} 243 <p> 244 The Zig code sample above demonstrates one way to create a program that will output <code>Hello, world!</code>. 245 </p> 246 <p> 247 The code sample shows the contents of a file named <code>hello.zig</code>. Files storing Zig 248 source code are {#link|UTF-8 encoded|Source Encoding#} text files. The files storing 249 Zig source code are usually named with the <code>.zig</code> extension. 250 </p> 251 <p> 252 Following the <code>hello.zig</code> Zig code sample, the {#link|Zig Build System#} is used 253 to build an executable program from the <code>hello.zig</code> source code. Then, the 254 <code>hello</code> program is executed showing its output <code>Hello, world!</code>. The 255 lines beginning with <code>$</code> represent command line prompts and a command. 256 Everything else is program output. 257 </p> 258 <p> 259 The code sample begins by adding Zig's Standard Library to the build using the {#link|@import#} builtin function. 260 The {#syntax#}@import("std"){#endsyntax#} function call creates a structure to represent the Standard Library. 261 The code then makes a {#link|top-level declaration|Global Variables#} of a 262 {#link|constant identifier|Assignment#}, named <code>std</code>, for easy access to 263 <a href="https://github.com/ziglang/zig/wiki/FAQ#where-is-the-documentation-for-the-zig-standard-library">Zig's standard library</a>. 264 </p> 265 <p> 266 Next, a {#link|public function|Functions#}, {#syntax#}pub fn{#endsyntax#}, named <code>main</code> 267 is declared. The <code>main</code> function is necessary because it tells the Zig compiler where the start of 268 the program exists. Programs designed to be executed will need a {#syntax#}pub fn main{#endsyntax#} function. 269 For more advanced use cases, Zig offers other features to inform the compiler where the start of 270 the program exists. Libraries, on the other hand, do not need a <code>main</code> function because 271 library code is usually called by other programs. 272 </p> 273 <p> 274 A function is a block of any number of statements and expressions that, as a whole, perform a task. 275 Functions may or may not return data after they are done performing their task. If a function 276 cannot perform its task, it might return an error. Zig makes all of this explicit. 277 </p> 278 <p> 279 In the <code>hello.zig</code> code sample, the <code>main</code> function is declared 280 with the {#syntax#}!void{#endsyntax#} return type. This return type is known as an {#link|Error Union Type#}. 281 This syntax tells the Zig compiler that the function will either return an 282 error or a value. An error union type combines an {#link|Error Set Type#} and a {#link|Primitive Type|Primitive Types#}. 283 The full form of an error union type is 284 <code><error set type></code>{#syntax#}!{#endsyntax#}<code><primitive type></code>. In the code 285 sample, the error set type is not explicitly written on the left side of the {#syntax#}!{#endsyntax#} operator. 286 When written this way, the error set type is a special kind of error union type that has an 287 {#link|inferred error set type|Inferred Error Sets#}. The {#syntax#}void{#endsyntax#} after the {#syntax#}!{#endsyntax#} operator 288 tells the compiler that the function will not return a value under normal circumstances (i.e. no errors occur). 289 </p> 290 <p> 291 Note to experienced programmers: Zig also has the boolean {#link|operator|Operators#} {#syntax#}!a{#endsyntax#} 292 where {#syntax#}a{#endsyntax#} is a value of type {#syntax#}bool{#endsyntax#}. Error union types contain the 293 name of the type in the syntax: {#syntax#}!{#endsyntax#}<code><primitive type></code>. 294 </p> 295 <p> 296 In Zig, a function's block of statements and expressions are surrounded by <code>{</code> and 297 <code>}</code> curly-braces. Inside of the <code>main</code> function are expressions that perform 298 the task of outputting <code>Hello, world!</code> to standard output. 299 </p> 300 <p> 301 First, a constant identifier, <code>stdout</code>, is initialized to represent standard output's 302 writer. Then, the program tries to print the <code>Hello, world!</code> 303 message to standard output. 304 </p> 305 <p> 306 Functions sometimes need information to perform their task. In Zig, information is passed 307 to functions between open <code>(</code> and close <code>)</code> parenthesis placed after 308 the function's name. This information is also known as arguments. When there are 309 multiple arguments passed to a function, they are separated by commas <code>,</code>. 310 </p> 311 <p> 312 The two arguments passed to the <code>stdout.print()</code> function, <code>"Hello, {s}!\n"</code> 313 and <code>.{"world"}</code>, are evaluated at {#link|compile-time|comptime#}. The code sample is 314 purposely written to show how to perform {#link|string|String Literals and Unicode Code Point Literals#} 315 substitution in the <code>print</code> function. The curly-braces inside of the first argument 316 are substituted with the compile-time known value inside of the second argument 317 (known as an {#link|anonymous struct literal|Anonymous Struct Literals#}). The <code>\n</code> 318 inside of the double-quotes of the first argument is the {#link|escape sequence|Escape Sequences#} for the 319 newline character. The {#link|try#} expression evaluates the result of <code>stdout.print</code>. 320 If the result is an error, then the {#syntax#}try{#endsyntax#} expression will return from 321 <code>main</code> with the error. Otherwise, the program will continue. In this case, there are no 322 more statements or expressions left to execute in the <code>main</code> function, so the program exits. 323 </p> 324 <p> 325 In Zig, the standard output writer's <code>print</code> function is allowed to fail because 326 it is actually a function defined as part of a generic Writer. Consider a generic Writer that 327 represents writing data to a file. When the disk is full, a write to the file will fail. 328 However, we typically do not expect writing text to the standard output to fail. To avoid having 329 to handle the failure case of printing to standard output, you can use alternate functions: the 330 functions in <code>std.log</code> for proper logging or the <code>std.debug.print</code> function. 331 This documentation will use the latter option to print to standard error (stderr) and silently return 332 on failure. The next code sample, <code>hello_again.zig</code> demonstrates the use of 333 <code>std.debug.print</code>. 334 </p> 335 {#code_begin|exe|hello_again#} 336 const print = @import("std").debug.print; 337 338 pub fn main() void { 339 print("Hello, world!\n", .{}); 340 } 341 {#code_end#} 342 <p> 343 Note that you can leave off the {#syntax#}!{#endsyntax#} from the return type because <code>std.debug.print</code> cannot fail. 344 </p> 345 {#see_also|Values|@import|Errors|Root Source File|Source Encoding#} 346 {#header_close#} 347 {#header_open|Comments#} 348 {#code_begin|test|comments#} 349 const expect = @import("std").testing.expect; 350 351 test "comments" { 352 // Comments in Zig start with "//" and end at the next LF byte (end of line). 353 // The below line is a comment, and won't be executed. 354 355 //expect(false); 356 357 const x = true; // another comment 358 try expect(x); 359 } 360 {#code_end#} 361 <p> 362 There are no multiline comments in Zig (e.g. like <code class="c">/* */</code> 363 comments in C). This helps allow Zig to have the property that each line 364 of code can be tokenized out of context. 365 </p> 366 {#header_open|Doc comments#} 367 <p> 368 A doc comment is one that begins with exactly three slashes (i.e. 369 {#syntax#}///{#endsyntax#} but not {#syntax#}////{#endsyntax#}); 370 multiple doc comments in a row are merged together to form a multiline 371 doc comment. The doc comment documents whatever immediately follows it. 372 </p> 373 {#code_begin|syntax|doc_comments#} 374 /// A structure for storing a timestamp, with nanosecond precision (this is a 375 /// multiline doc comment). 376 const Timestamp = struct { 377 /// The number of seconds since the epoch (this is also a doc comment). 378 seconds: i64, // signed so we can represent pre-1970 (not a doc comment) 379 /// The number of nanoseconds past the second (doc comment again). 380 nanos: u32, 381 382 /// Returns a `Timestamp` struct representing the Unix epoch; that is, the 383 /// moment of 1970 Jan 1 00:00:00 UTC (this is a doc comment too). 384 pub fn unixEpoch() Timestamp { 385 return Timestamp{ 386 .seconds = 0, 387 .nanos = 0, 388 }; 389 } 390 }; 391 {#code_end#} 392 <p> 393 Doc comments are only allowed in certain places; eventually, it will 394 become a compile error to have a doc comment in an unexpected place, such as 395 in the middle of an expression, or just before a non-doc comment. 396 </p> 397 {#header_close#} 398 {#header_open|Top-Level Doc Comments#} 399 <p>User documentation that doesn't belong to whatever 400 immediately follows it, like package-level documentation, goes 401 in top-level doc comments. A top-level doc comment is one that 402 begins with two slashes and an exclamation point: 403 {#syntax#}//!{#endsyntax#}.</p> 404 {#code_begin|syntax|tldoc_comments#} 405 //! This module provides functions for retrieving the current date and 406 //! time with varying degrees of precision and accuracy. It does not 407 //! depend on libc, but will use functions from it if available. 408 {#code_end#} 409 {#header_close#} 410 {#header_close#} 411 {#header_open|Values#} 412 {#code_begin|exe|values#} 413 // Top-level declarations are order-independent: 414 const print = std.debug.print; 415 const std = @import("std"); 416 const os = std.os; 417 const assert = std.debug.assert; 418 419 pub fn main() void { 420 // integers 421 const one_plus_one: i32 = 1 + 1; 422 print("1 + 1 = {}\n", .{one_plus_one}); 423 424 // floats 425 const seven_div_three: f32 = 7.0 / 3.0; 426 print("7.0 / 3.0 = {}\n", .{seven_div_three}); 427 428 // boolean 429 print("{}\n{}\n{}\n", .{ 430 true and false, 431 true or false, 432 !true, 433 }); 434 435 // optional 436 var optional_value: ?[]const u8 = null; 437 assert(optional_value == null); 438 439 print("\noptional 1\ntype: {s}\nvalue: {s}\n", .{ 440 @typeName(@TypeOf(optional_value)), 441 optional_value, 442 }); 443 444 optional_value = "hi"; 445 assert(optional_value != null); 446 447 print("\noptional 2\ntype: {s}\nvalue: {s}\n", .{ 448 @typeName(@TypeOf(optional_value)), 449 optional_value, 450 }); 451 452 // error union 453 var number_or_error: anyerror!i32 = error.ArgNotFound; 454 455 print("\nerror union 1\ntype: {s}\nvalue: {}\n", .{ 456 @typeName(@TypeOf(number_or_error)), 457 number_or_error, 458 }); 459 460 number_or_error = 1234; 461 462 print("\nerror union 2\ntype: {s}\nvalue: {}\n", .{ 463 @typeName(@TypeOf(number_or_error)), 464 number_or_error, 465 }); 466 } 467 {#code_end#} 468 {#header_open|Primitive Types#} 469 <div class="table-wrapper"> 470 <table> 471 <tr> 472 <th> 473 Name 474 </th> 475 <th> 476 C Equivalent 477 </th> 478 <th> 479 Description 480 </th> 481 </tr> 482 <tr> 483 <td>{#syntax#}i8{#endsyntax#}</td> 484 <td><code class="c">int8_t</code></td> 485 <td>signed 8-bit integer</td> 486 </tr> 487 <tr> 488 <td>{#syntax#}u8{#endsyntax#}</td> 489 <td><code class="c">uint8_t</code></td> 490 <td>unsigned 8-bit integer</td> 491 </tr> 492 <tr> 493 <td>{#syntax#}i16{#endsyntax#}</td> 494 <td><code class="c">int16_t</code></td> 495 <td>signed 16-bit integer</td> 496 </tr> 497 <tr> 498 <td>{#syntax#}u16{#endsyntax#}</td> 499 <td><code class="c">uint16_t</code></td> 500 <td>unsigned 16-bit integer</td> 501 </tr> 502 <tr> 503 <td>{#syntax#}i32{#endsyntax#}</td> 504 <td><code class="c">int32_t</code></td> 505 <td>signed 32-bit integer</td> 506 </tr> 507 <tr> 508 <td>{#syntax#}u32{#endsyntax#}</td> 509 <td><code class="c">uint32_t</code></td> 510 <td>unsigned 32-bit integer</td> 511 </tr> 512 <tr> 513 <td>{#syntax#}i64{#endsyntax#}</td> 514 <td><code class="c">int64_t</code></td> 515 <td>signed 64-bit integer</td> 516 </tr> 517 <tr> 518 <td>{#syntax#}u64{#endsyntax#}</td> 519 <td><code class="c">uint64_t</code></td> 520 <td>unsigned 64-bit integer</td> 521 </tr> 522 <tr> 523 <td>{#syntax#}i128{#endsyntax#}</td> 524 <td><code class="c">__int128</code></td> 525 <td>signed 128-bit integer</td> 526 </tr> 527 <tr> 528 <td>{#syntax#}u128{#endsyntax#}</td> 529 <td><code class="c">unsigned __int128</code></td> 530 <td>unsigned 128-bit integer</td> 531 </tr> 532 <tr> 533 <td>{#syntax#}isize{#endsyntax#}</td> 534 <td><code class="c">intptr_t</code></td> 535 <td>signed pointer sized integer</td> 536 </tr> 537 <tr> 538 <td>{#syntax#}usize{#endsyntax#}</td> 539 <td><code class="c">uintptr_t</code></td> 540 <td>unsigned pointer sized integer</td> 541 </tr> 542 543 <tr> 544 <td>{#syntax#}c_short{#endsyntax#}</td> 545 <td><code class="c">short</code></td> 546 <td>for ABI compatibility with C</td> 547 </tr> 548 <tr> 549 <td>{#syntax#}c_ushort{#endsyntax#}</td> 550 <td><code class="c">unsigned short</code></td> 551 <td>for ABI compatibility with C</td> 552 </tr> 553 <tr> 554 <td>{#syntax#}c_int{#endsyntax#}</td> 555 <td><code class="c">int</code></td> 556 <td>for ABI compatibility with C</td> 557 </tr> 558 <tr> 559 <td>{#syntax#}c_uint{#endsyntax#}</td> 560 <td><code class="c">unsigned int</code></td> 561 <td>for ABI compatibility with C</td> 562 </tr> 563 <tr> 564 <td>{#syntax#}c_long{#endsyntax#}</td> 565 <td><code class="c">long</code></td> 566 <td>for ABI compatibility with C</td> 567 </tr> 568 <tr> 569 <td>{#syntax#}c_ulong{#endsyntax#}</td> 570 <td><code class="c">unsigned long</code></td> 571 <td>for ABI compatibility with C</td> 572 </tr> 573 <tr> 574 <td>{#syntax#}c_longlong{#endsyntax#}</td> 575 <td><code class="c">long long</code></td> 576 <td>for ABI compatibility with C</td> 577 </tr> 578 <tr> 579 <td>{#syntax#}c_ulonglong{#endsyntax#}</td> 580 <td><code class="c">unsigned long long</code></td> 581 <td>for ABI compatibility with C</td> 582 </tr> 583 <tr> 584 <td>{#syntax#}c_longdouble{#endsyntax#}</td> 585 <td><code class="c">long double</code></td> 586 <td>for ABI compatibility with C</td> 587 </tr> 588 <tr> 589 <td>{#syntax#}c_void{#endsyntax#}</td> 590 <td><code class="c">void</code></td> 591 <td>for ABI compatibility with C</td> 592 </tr> 593 594 <tr> 595 <td>{#syntax#}f16{#endsyntax#}</td> 596 <td><code class="c">_Float16</code></td> 597 <td>16-bit floating point (10-bit mantissa) IEEE-754-2008 binary16</td> 598 </tr> 599 <tr> 600 <td>{#syntax#}f32{#endsyntax#}</td> 601 <td><code class="c">float</code></td> 602 <td>32-bit floating point (23-bit mantissa) IEEE-754-2008 binary32</td> 603 </tr> 604 <tr> 605 <td>{#syntax#}f64{#endsyntax#}</td> 606 <td><code class="c">double</code></td> 607 <td>64-bit floating point (52-bit mantissa) IEEE-754-2008 binary64</td> 608 </tr> 609 <tr> 610 <td>{#syntax#}f128{#endsyntax#}</td> 611 <td><code class="c">_Float128</code></td> 612 <td>128-bit floating point (112-bit mantissa) IEEE-754-2008 binary128</td> 613 </tr> 614 <tr> 615 <td>{#syntax#}bool{#endsyntax#}</td> 616 <td><code class="c">bool</code></td> 617 <td>{#syntax#}true{#endsyntax#} or {#syntax#}false{#endsyntax#}</td> 618 </tr> 619 <tr> 620 <td>{#syntax#}void{#endsyntax#}</td> 621 <td>(none)</td> 622 <td>0 bit type</td> 623 </tr> 624 <tr> 625 <td>{#syntax#}noreturn{#endsyntax#}</td> 626 <td>(none)</td> 627 <td>the type of {#syntax#}break{#endsyntax#}, {#syntax#}continue{#endsyntax#}, {#syntax#}return{#endsyntax#}, {#syntax#}unreachable{#endsyntax#}, and {#syntax#}while (true) {}{#endsyntax#}</td> 628 </tr> 629 <tr> 630 <td>{#syntax#}type{#endsyntax#}</td> 631 <td>(none)</td> 632 <td>the type of types</td> 633 </tr> 634 <tr> 635 <td>{#syntax#}anyerror{#endsyntax#}</td> 636 <td>(none)</td> 637 <td>an error code</td> 638 </tr> 639 <tr> 640 <td>{#syntax#}comptime_int{#endsyntax#}</td> 641 <td>(none)</td> 642 <td>Only allowed for {#link|comptime#}-known values. The type of integer literals.</td> 643 </tr> 644 <tr> 645 <td>{#syntax#}comptime_float{#endsyntax#}</td> 646 <td>(none)</td> 647 <td>Only allowed for {#link|comptime#}-known values. The type of float literals.</td> 648 </tr> 649 </table> 650 </div> 651 <p> 652 In addition to the integer types above, arbitrary bit-width integers can be referenced by using 653 an identifier of <code>i</code> or <code>u</code> followed by digits. For example, the identifier 654 {#syntax#}i7{#endsyntax#} refers to a signed 7-bit integer. The maximum allowed bit-width of an 655 integer type is {#syntax#}65535{#endsyntax#}. 656 </p> 657 {#see_also|Integers|Floats|void|Errors|@Type#} 658 {#header_close#} 659 {#header_open|Primitive Values#} 660 <div class="table-wrapper"> 661 <table> 662 <tr> 663 <th> 664 Name 665 </th> 666 <th> 667 Description 668 </th> 669 </tr> 670 <tr> 671 <td>{#syntax#}true{#endsyntax#} and {#syntax#}false{#endsyntax#}</td> 672 <td>{#syntax#}bool{#endsyntax#} values</td> 673 </tr> 674 <tr> 675 <td>{#syntax#}null{#endsyntax#}</td> 676 <td>used to set an optional type to {#syntax#}null{#endsyntax#}</td> 677 </tr> 678 <tr> 679 <td>{#syntax#}undefined{#endsyntax#}</td> 680 <td>used to leave a value unspecified</td> 681 </tr> 682 </table> 683 </div> 684 {#see_also|Optionals|undefined#} 685 {#header_close#} 686 {#header_open|String Literals and Unicode Code Point Literals#} 687 <p> 688 String literals are constant single-item {#link|Pointers#} to null-terminated byte arrays. 689 The type of string literals encodes both the length, and the fact that they are null-terminated, 690 and thus they can be {#link|coerced|Type Coercion#} to both {#link|Slices#} and 691 {#link|Null-Terminated Pointers|Sentinel-Terminated Pointers#}. 692 Dereferencing string literals converts them to {#link|Arrays#}. 693 </p> 694 <p> 695 The encoding of a string in Zig is de-facto assumed to be UTF-8. 696 Because Zig source code is {#link|UTF-8 encoded|Source Encoding#}, any non-ASCII bytes appearing within a string literal 697 in source code carry their UTF-8 meaning into the content of the string in the Zig program; 698 the bytes are not modified by the compiler. 699 However, it is possible to embbed non-UTF-8 bytes into a string literal using <code>\xNN</code> notation. 700 </p> 701 <p> 702 Unicode code point literals have type {#syntax#}comptime_int{#endsyntax#}, the same as 703 {#link|Integer Literals#}. All {#link|Escape Sequences#} are valid in both string literals 704 and Unicode code point literals. 705 </p> 706 <p> 707 In many other programming languages, a Unicode code point literal is called a "character literal". 708 However, there is <a href="https://unicode.org/glossary">no precise technical definition of a "character"</a> 709 in recent versions of the Unicode specification (as of Unicode 13.0). 710 In Zig, a Unicode code point literal corresponds to the Unicode definition of a code point. 711 </p> 712 {#code_begin|test#} 713 const expect = @import("std").testing.expect; 714 const mem = @import("std").mem; 715 716 test "string literals" { 717 const bytes = "hello"; 718 try expect(@TypeOf(bytes) == *const [5:0]u8); 719 try expect(bytes.len == 5); 720 try expect(bytes[1] == 'e'); 721 try expect(bytes[5] == 0); 722 try expect('e' == '\x65'); 723 try expect('\u{1f4a9}' == 128169); 724 try expect('💯' == 128175); 725 try expect(mem.eql(u8, "hello", "h\x65llo")); 726 try expect("\xff"[0] == 0xff); // non-UTF-8 strings are possible with \xNN notation. 727 } 728 {#code_end#} 729 {#see_also|Arrays|Zig Test|Source Encoding#} 730 {#header_open|Escape Sequences#} 731 <div class="table-wrapper"> 732 <table> 733 <tr> 734 <th> 735 Escape Sequence 736 </th> 737 <th> 738 Name 739 </th> 740 </tr> 741 <tr> 742 <td><code>\n</code></td> 743 <td>Newline</td> 744 </tr> 745 <tr> 746 <td><code>\r</code></td> 747 <td>Carriage Return</td> 748 </tr> 749 <tr> 750 <td><code>\t</code></td> 751 <td>Tab</td> 752 </tr> 753 <tr> 754 <td><code>\\</code></td> 755 <td>Backslash</td> 756 </tr> 757 <tr> 758 <td><code>\'</code></td> 759 <td>Single Quote</td> 760 </tr> 761 <tr> 762 <td><code>\"</code></td> 763 <td>Double Quote</td> 764 </tr> 765 <tr> 766 <td><code>\xNN</code></td> 767 <td>hexadecimal 8-bit byte value (2 digits)</td> 768 </tr> 769 <tr> 770 <td><code>\u{NNNNNN}</code></td> 771 <td>hexadecimal Unicode code point UTF-8 encoded (1 or more digits)</td> 772 </tr> 773 </table> 774 </div> 775 <p>Note that the maximum valid Unicode point is {#syntax#}0x10ffff{#endsyntax#}.</p> 776 {#header_close#} 777 {#header_open|Multiline String Literals#} 778 <p> 779 Multiline string literals have no escapes and can span across multiple lines. 780 To start a multiline string literal, use the {#syntax#}\\{#endsyntax#} token. Just like a comment, 781 the string literal goes until the end of the line. The end of the line is 782 not included in the string literal. 783 However, if the next line begins with {#syntax#}\\{#endsyntax#} then a newline is appended and 784 the string literal continues. 785 </p> 786 {#code_begin|syntax#} 787 const hello_world_in_c = 788 \\#include <stdio.h> 789 \\ 790 \\int main(int argc, char **argv) { 791 \\ printf("hello world\n"); 792 \\ return 0; 793 \\} 794 ; 795 {#code_end#} 796 {#see_also|@embedFile#} 797 {#header_close#} 798 {#header_close#} 799 {#header_open|Assignment#} 800 <p>Use the {#syntax#}const{#endsyntax#} keyword to assign a value to an identifier:</p> 801 {#code_begin|test_err|cannot assign to constant#} 802 const x = 1234; 803 804 fn foo() void { 805 // It works at global scope as well as inside functions. 806 const y = 5678; 807 808 // Once assigned, an identifier cannot be changed. 809 y += 1; 810 } 811 812 test "assignment" { 813 foo(); 814 } 815 {#code_end#} 816 <p>{#syntax#}const{#endsyntax#} applies to all of the bytes that the identifier immediately addresses. {#link|Pointers#} have their own const-ness.</p> 817 <p>If you need a variable that you can modify, use the {#syntax#}var{#endsyntax#} keyword:</p> 818 {#code_begin|test#} 819 const expect = @import("std").testing.expect; 820 821 test "var" { 822 var y: i32 = 5678; 823 824 y += 1; 825 826 try expect(y == 5679); 827 } 828 {#code_end#} 829 <p>Variables must be initialized:</p> 830 {#code_begin|test_err#} 831 test "initialization" { 832 var x: i32; 833 834 x = 1; 835 } 836 {#code_end#} 837 {#header_open|undefined#} 838 <p>Use {#syntax#}undefined{#endsyntax#} to leave variables uninitialized:</p> 839 {#code_begin|test#} 840 const expect = @import("std").testing.expect; 841 842 test "init with undefined" { 843 var x: i32 = undefined; 844 x = 1; 845 try expect(x == 1); 846 } 847 {#code_end#} 848 <p> 849 {#syntax#}undefined{#endsyntax#} can be {#link|coerced|Type Coercion#} to any type. 850 Once this happens, it is no longer possible to detect that the value is {#syntax#}undefined{#endsyntax#}. 851 {#syntax#}undefined{#endsyntax#} means the value could be anything, even something that is nonsense 852 according to the type. Translated into English, {#syntax#}undefined{#endsyntax#} means "Not a meaningful 853 value. Using this value would be a bug. The value will be unused, or overwritten before being used." 854 </p> 855 <p> 856 In {#link|Debug#} mode, Zig writes {#syntax#}0xaa{#endsyntax#} bytes to undefined memory. This is to catch 857 bugs early, and to help detect use of undefined memory in a debugger. 858 </p> 859 {#header_close#} 860 {#header_close#} 861 {#header_close#} 862 863 {#header_open|Variables#} 864 <p> 865 A variable is a unit of {#link|Memory#} storage. 866 </p> 867 <p> 868 Variables are never allowed to shadow identifiers from an outer scope. 869 </p> 870 <p> 871 It is generally preferable to use {#syntax#}const{#endsyntax#} rather than 872 {#syntax#}var{#endsyntax#} when declaring a variable. This causes less work for both 873 humans and computers to do when reading code, and creates more optimization opportunities. 874 </p> 875 {#header_open|Global Variables#} 876 <p> 877 Global variables are considered to be a top level declaration, which means that they are 878 order-independent and lazily analyzed. The initialization value of global variables is implicitly 879 {#link|comptime#}. If a global variable is {#syntax#}const{#endsyntax#} then its value is 880 {#syntax#}comptime{#endsyntax#}-known, otherwise it is runtime-known. 881 </p> 882 {#code_begin|test|global_variables#} 883 var y: i32 = add(10, x); 884 const x: i32 = add(12, 34); 885 886 test "global variables" { 887 try expect(x == 46); 888 try expect(y == 56); 889 } 890 891 fn add(a: i32, b: i32) i32 { 892 return a + b; 893 } 894 895 const std = @import("std"); 896 const expect = std.testing.expect; 897 {#code_end#} 898 <p> 899 Global variables may be declared inside a {#link|struct#}, {#link|union#}, or {#link|enum#}: 900 </p> 901 {#code_begin|test|namespaced_global#} 902 const std = @import("std"); 903 const expect = std.testing.expect; 904 905 test "namespaced global variable" { 906 try expect(foo() == 1235); 907 try expect(foo() == 1236); 908 } 909 910 fn foo() i32 { 911 const S = struct { 912 var x: i32 = 1234; 913 }; 914 S.x += 1; 915 return S.x; 916 } 917 {#code_end#} 918 <p> 919 The {#syntax#}extern{#endsyntax#} keyword can be used to link against a variable that is exported 920 from another object. The {#syntax#}export{#endsyntax#} keyword or {#link|@export#} builtin function 921 can be used to make a variable available to other objects at link time. In both cases, 922 the type of the variable must be C ABI compatible. 923 </p> 924 {#see_also|Exporting a C Library#} 925 {#header_close#} 926 927 {#header_open|Thread Local Variables#} 928 <p>A variable may be specified to be a thread-local variable using the 929 {#syntax#}threadlocal{#endsyntax#} keyword:</p> 930 {#code_begin|test|tls#} 931 const std = @import("std"); 932 const assert = std.debug.assert; 933 934 threadlocal var x: i32 = 1234; 935 936 test "thread local storage" { 937 const thread1 = try std.Thread.spawn(testTls, {}); 938 const thread2 = try std.Thread.spawn(testTls, {}); 939 testTls({}); 940 thread1.wait(); 941 thread2.wait(); 942 } 943 944 fn testTls(context: void) void { 945 assert(x == 1234); 946 x += 1; 947 assert(x == 1235); 948 } 949 {#code_end#} 950 <p> 951 For {#link|Single Threaded Builds#}, all thread local variables are treated as {#link|Global Variables#}. 952 </p> 953 <p> 954 Thread local variables may not be {#syntax#}const{#endsyntax#}. 955 </p> 956 {#header_close#} 957 958 {#header_open|Local Variables#} 959 <p> 960 Local variables occur inside {#link|Functions#}, {#link|comptime#} blocks, and {#link|@cImport#} blocks. 961 </p> 962 <p> 963 When a local variable is {#syntax#}const{#endsyntax#}, it means that after initialization, the variable's 964 value will not change. If the initialization value of a {#syntax#}const{#endsyntax#} variable is 965 {#link|comptime#}-known, then the variable is also {#syntax#}comptime{#endsyntax#}-known. 966 </p> 967 <p> 968 A local variable may be qualified with the {#syntax#}comptime{#endsyntax#} keyword. This causes 969 the variable's value to be {#syntax#}comptime{#endsyntax#}-known, and all loads and stores of the 970 variable to happen during semantic analysis of the program, rather than at runtime. 971 All variables declared in a {#syntax#}comptime{#endsyntax#} expression are implicitly 972 {#syntax#}comptime{#endsyntax#} variables. 973 </p> 974 {#code_begin|test|comptime_vars#} 975 const std = @import("std"); 976 const expect = std.testing.expect; 977 978 test "comptime vars" { 979 var x: i32 = 1; 980 comptime var y: i32 = 1; 981 982 x += 1; 983 y += 1; 984 985 try expect(x == 2); 986 try expect(y == 2); 987 988 if (y != 2) { 989 // This compile error never triggers because y is a comptime variable, 990 // and so `y != 2` is a comptime value, and this if is statically evaluated. 991 @compileError("wrong y value"); 992 } 993 } 994 {#code_end#} 995 {#header_close#} 996 {#header_close#} 997 998 {#header_open|Integers#} 999 {#header_open|Integer Literals#} 1000 {#code_begin|syntax#} 1001 const decimal_int = 98222; 1002 const hex_int = 0xff; 1003 const another_hex_int = 0xFF; 1004 const octal_int = 0o755; 1005 const binary_int = 0b11110000; 1006 1007 // underscores may be placed between two digits as a visual separator 1008 const one_billion = 1_000_000_000; 1009 const binary_mask = 0b1_1111_1111; 1010 const permissions = 0o7_5_5; 1011 const big_address = 0xFF80_0000_0000_0000; 1012 {#code_end#} 1013 {#header_close#} 1014 {#header_open|Runtime Integer Values#} 1015 <p> 1016 Integer literals have no size limitation, and if any undefined behavior occurs, 1017 the compiler catches it. 1018 </p> 1019 <p> 1020 However, once an integer value is no longer known at compile-time, it must have a 1021 known size, and is vulnerable to undefined behavior. 1022 </p> 1023 {#code_begin|syntax#} 1024 fn divide(a: i32, b: i32) i32 { 1025 return a / b; 1026 } 1027 {#code_end#} 1028 <p> 1029 In this function, values {#syntax#}a{#endsyntax#} and {#syntax#}b{#endsyntax#} are known only at runtime, 1030 and thus this division operation is vulnerable to both {#link|Integer Overflow#} and 1031 {#link|Division by Zero#}. 1032 </p> 1033 <p> 1034 Operators such as {#syntax#}+{#endsyntax#} and {#syntax#}-{#endsyntax#} cause undefined behavior on 1035 integer overflow. Also available are operations such as {#syntax#}+%{#endsyntax#} and 1036 {#syntax#}-%{#endsyntax#} which are defined to have wrapping arithmetic on all targets. 1037 </p> 1038 <p> 1039 Zig supports arbitrary bit-width integers, referenced by using 1040 an identifier of <code>i</code> or <code>u</code> followed by digits. For example, the identifier 1041 {#syntax#}i7{#endsyntax#} refers to a signed 7-bit integer. The maximum allowed bit-width of an 1042 integer type is {#syntax#}65535{#endsyntax#}. 1043 </p> 1044 {#see_also|Wrapping Operations#} 1045 {#header_close#} 1046 {#header_close#} 1047 {#header_open|Floats#} 1048 <p>Zig has the following floating point types:</p> 1049 <ul> 1050 <li>{#syntax#}f16{#endsyntax#} - IEEE-754-2008 binary16</li> 1051 <li>{#syntax#}f32{#endsyntax#} - IEEE-754-2008 binary32</li> 1052 <li>{#syntax#}f64{#endsyntax#} - IEEE-754-2008 binary64</li> 1053 <li>{#syntax#}f128{#endsyntax#} - IEEE-754-2008 binary128</li> 1054 <li>{#syntax#}c_longdouble{#endsyntax#} - matches <code class="c">long double</code> for the target C ABI</li> 1055 </ul> 1056 {#header_open|Float Literals#} 1057 <p> 1058 Float literals have type {#syntax#}comptime_float{#endsyntax#} which is guaranteed to have 1059 the same precision and operations of the largest other floating point type, which is 1060 {#syntax#}f128{#endsyntax#}. 1061 </p> 1062 <p> 1063 Float literals {#link|coerce|Type Coercion#} to any floating point type, 1064 and to any {#link|integer|Integers#} type when there is no fractional component. 1065 </p> 1066 {#code_begin|syntax#} 1067 const floating_point = 123.0E+77; 1068 const another_float = 123.0; 1069 const yet_another = 123.0e+77; 1070 1071 const hex_floating_point = 0x103.70p-5; 1072 const another_hex_float = 0x103.70; 1073 const yet_another_hex_float = 0x103.70P-5; 1074 1075 // underscores may be placed between two digits as a visual separator 1076 const lightspeed = 299_792_458.000_000; 1077 const nanosecond = 0.000_000_001; 1078 const more_hex = 0x1234_5678.9ABC_CDEFp-10; 1079 {#code_end#} 1080 <p> 1081 There is no syntax for NaN, infinity, or negative infinity. For these special values, 1082 one must use the standard library: 1083 </p> 1084 {#code_begin|syntax#} 1085 const std = @import("std"); 1086 1087 const inf = std.math.inf(f32); 1088 const negative_inf = -std.math.inf(f64); 1089 const nan = std.math.nan(f128); 1090 {#code_end#} 1091 {#header_close#} 1092 {#header_open|Floating Point Operations#} 1093 <p>By default floating point operations use {#syntax#}Strict{#endsyntax#} mode, 1094 but you can switch to {#syntax#}Optimized{#endsyntax#} mode on a per-block basis:</p> 1095 {#code_begin|obj|foo#} 1096 {#code_release_fast#} 1097 {#code_disable_cache#} 1098 const std = @import("std"); 1099 const big = @as(f64, 1 << 40); 1100 1101 export fn foo_strict(x: f64) f64 { 1102 return x + big - big; 1103 } 1104 1105 export fn foo_optimized(x: f64) f64 { 1106 @setFloatMode(.Optimized); 1107 return x + big - big; 1108 } 1109 {#code_end#} 1110 <p>For this test we have to separate code into two object files - 1111 otherwise the optimizer figures out all the values at compile-time, 1112 which operates in strict mode.</p> 1113 {#code_begin|exe|float_mode#} 1114 {#code_link_object|foo#} 1115 const print = @import("std").debug.print; 1116 1117 extern fn foo_strict(x: f64) f64; 1118 extern fn foo_optimized(x: f64) f64; 1119 1120 pub fn main() void { 1121 const x = 0.001; 1122 print("optimized = {}\n", .{foo_optimized(x)}); 1123 print("strict = {}\n", .{foo_strict(x)}); 1124 } 1125 {#code_end#} 1126 {#see_also|@setFloatMode|Division by Zero#} 1127 {#header_close#} 1128 {#header_close#} 1129 {#header_open|Operators#} 1130 <p> 1131 There is no operator overloading. When you see an operator in Zig, you know that 1132 it is doing something from this table, and nothing else. 1133 </p> 1134 {#header_open|Table of Operators#} 1135 <div class="table-wrapper"> 1136 <table> 1137 <tr> 1138 <th> 1139 Syntax 1140 </th> 1141 <th> 1142 Relevant Types 1143 </th> 1144 <th> 1145 Description 1146 </th> 1147 <th> 1148 Example 1149 </th> 1150 </tr> 1151 <tr> 1152 <td><pre>{#syntax#}a + b 1153 a += b{#endsyntax#}</pre></td> 1154 <td> 1155 <ul> 1156 <li>{#link|Integers#}</li> 1157 <li>{#link|Floats#}</li> 1158 </ul> 1159 </td> 1160 <td>Addition. 1161 <ul> 1162 <li>Can cause {#link|overflow|Default Operations#} for integers.</li> 1163 <li>Invokes {#link|Peer Type Resolution#} for the operands.</li> 1164 <li>See also {#link|@addWithOverflow#}.</li> 1165 </ul> 1166 </td> 1167 <td> 1168 <pre>{#syntax#}2 + 5 == 7{#endsyntax#}</pre> 1169 </td> 1170 </tr> 1171 <tr> 1172 <td><pre>{#syntax#}a +% b 1173 a +%= b{#endsyntax#}</pre></td> 1174 <td> 1175 <ul> 1176 <li>{#link|Integers#}</li> 1177 </ul> 1178 </td> 1179 <td>Wrapping Addition. 1180 <ul> 1181 <li>Guaranteed to have twos-complement wrapping behavior.</li> 1182 <li>Invokes {#link|Peer Type Resolution#} for the operands.</li> 1183 <li>See also {#link|@addWithOverflow#}.</li> 1184 </ul> 1185 </td> 1186 <td> 1187 <pre>{#syntax#}@as(u32, std.math.maxInt(u32)) +% 1 == 0{#endsyntax#}</pre> 1188 </td> 1189 </tr> 1190 <tr> 1191 <td><pre>{#syntax#}a - b 1192 a -= b{#endsyntax#}</pre></td> 1193 <td> 1194 <ul> 1195 <li>{#link|Integers#}</li> 1196 <li>{#link|Floats#}</li> 1197 </ul> 1198 </td> 1199 <td>Subtraction. 1200 <ul> 1201 <li>Can cause {#link|overflow|Default Operations#} for integers.</li> 1202 <li>Invokes {#link|Peer Type Resolution#} for the operands.</li> 1203 <li>See also {#link|@subWithOverflow#}.</li> 1204 </ul> 1205 </td> 1206 <td> 1207 <pre>{#syntax#}2 - 5 == -3{#endsyntax#}</pre> 1208 </td> 1209 </tr> 1210 <tr> 1211 <td><pre>{#syntax#}a -% b 1212 a -%= b{#endsyntax#}</pre></td> 1213 <td> 1214 <ul> 1215 <li>{#link|Integers#}</li> 1216 </ul> 1217 </td> 1218 <td>Wrapping Subtraction. 1219 <ul> 1220 <li>Guaranteed to have twos-complement wrapping behavior.</li> 1221 <li>Invokes {#link|Peer Type Resolution#} for the operands.</li> 1222 <li>See also {#link|@subWithOverflow#}.</li> 1223 </ul> 1224 </td> 1225 <td> 1226 <pre>{#syntax#}@as(u32, 0) -% 1 == std.math.maxInt(u32){#endsyntax#}</pre> 1227 </td> 1228 </tr> 1229 <tr> 1230 <td><pre>{#syntax#}-a{#endsyntax#}</pre></td> 1231 <td> 1232 <ul> 1233 <li>{#link|Integers#}</li> 1234 <li>{#link|Floats#}</li> 1235 </ul> 1236 </td> 1237 <td> 1238 Negation. 1239 <ul> 1240 <li>Can cause {#link|overflow|Default Operations#} for integers.</li> 1241 </ul> 1242 </td> 1243 <td> 1244 <pre>{#syntax#}-1 == 0 - 1{#endsyntax#}</pre> 1245 </td> 1246 </tr> 1247 <tr> 1248 <td><pre>{#syntax#}-%a{#endsyntax#}</pre></td> 1249 <td> 1250 <ul> 1251 <li>{#link|Integers#}</li> 1252 </ul> 1253 </td> 1254 <td> 1255 Wrapping Negation. 1256 <ul> 1257 <li>Guaranteed to have twos-complement wrapping behavior.</li> 1258 </ul> 1259 </td> 1260 <td> 1261 <pre>{#syntax#}-%@as(i32, std.math.minInt(i32)) == std.math.minInt(i32){#endsyntax#}</pre> 1262 </td> 1263 </tr> 1264 <tr> 1265 <td><pre>{#syntax#}a * b 1266 a *= b{#endsyntax#}</pre></td> 1267 <td> 1268 <ul> 1269 <li>{#link|Integers#}</li> 1270 <li>{#link|Floats#}</li> 1271 </ul> 1272 </td> 1273 <td>Multiplication. 1274 <ul> 1275 <li>Can cause {#link|overflow|Default Operations#} for integers.</li> 1276 <li>Invokes {#link|Peer Type Resolution#} for the operands.</li> 1277 <li>See also {#link|@mulWithOverflow#}.</li> 1278 </ul> 1279 </td> 1280 <td> 1281 <pre>{#syntax#}2 * 5 == 10{#endsyntax#}</pre> 1282 </td> 1283 </tr> 1284 <tr> 1285 <td><pre>{#syntax#}a *% b 1286 a *%= b{#endsyntax#}</pre></td> 1287 <td> 1288 <ul> 1289 <li>{#link|Integers#}</li> 1290 </ul> 1291 </td> 1292 <td>Wrapping Multiplication. 1293 <ul> 1294 <li>Guaranteed to have twos-complement wrapping behavior.</li> 1295 <li>Invokes {#link|Peer Type Resolution#} for the operands.</li> 1296 <li>See also {#link|@mulWithOverflow#}.</li> 1297 </ul> 1298 </td> 1299 <td> 1300 <pre>{#syntax#}@as(u8, 200) *% 2 == 144{#endsyntax#}</pre> 1301 </td> 1302 </tr> 1303 <tr> 1304 <td><pre>{#syntax#}a / b 1305 a /= b{#endsyntax#}</pre></td> 1306 <td> 1307 <ul> 1308 <li>{#link|Integers#}</li> 1309 <li>{#link|Floats#}</li> 1310 </ul> 1311 </td> 1312 <td>Division. 1313 <ul> 1314 <li>Can cause {#link|overflow|Default Operations#} for integers.</li> 1315 <li>Can cause {#link|Division by Zero#} for integers.</li> 1316 <li>Can cause {#link|Division by Zero#} for floats in {#link|FloatMode.Optimized Mode|Floating Point Operations#}.</li> 1317 <li>Signed integer operands must be comptime-known and positive. In other cases, use 1318 {#link|@divTrunc#}, 1319 {#link|@divFloor#}, or 1320 {#link|@divExact#} instead. 1321 </li> 1322 <li>Invokes {#link|Peer Type Resolution#} for the operands.</li> 1323 </ul> 1324 </td> 1325 <td> 1326 <pre>{#syntax#}10 / 5 == 2{#endsyntax#}</pre> 1327 </td> 1328 </tr> 1329 <tr> 1330 <td><pre>{#syntax#}a % b 1331 a %= b{#endsyntax#}</pre></td> 1332 <td> 1333 <ul> 1334 <li>{#link|Integers#}</li> 1335 <li>{#link|Floats#}</li> 1336 </ul> 1337 </td> 1338 <td>Remainder Division. 1339 <ul> 1340 <li>Can cause {#link|Division by Zero#} for integers.</li> 1341 <li>Can cause {#link|Division by Zero#} for floats in {#link|FloatMode.Optimized Mode|Floating Point Operations#}.</li> 1342 <li>Signed or floating-point operands must be comptime-known and positive. In other cases, use 1343 {#link|@rem#} or 1344 {#link|@mod#} instead. 1345 </li> 1346 <li>Invokes {#link|Peer Type Resolution#} for the operands.</li> 1347 </ul> 1348 </td> 1349 <td> 1350 <pre>{#syntax#}10 % 3 == 1{#endsyntax#}</pre> 1351 </td> 1352 </tr> 1353 <tr> 1354 <td><pre>{#syntax#}a << b 1355 a <<= b{#endsyntax#}</pre></td> 1356 <td> 1357 <ul> 1358 <li>{#link|Integers#}</li> 1359 </ul> 1360 </td> 1361 <td>Bit Shift Left. 1362 <ul> 1363 <li>{#syntax#}b{#endsyntax#} must be {#link|comptime-known|comptime#} or have a type with log2 number of bits as {#syntax#}a{#endsyntax#}.</li> 1364 <li>See also {#link|@shlExact#}.</li> 1365 <li>See also {#link|@shlWithOverflow#}.</li> 1366 </ul> 1367 </td> 1368 <td> 1369 <pre>{#syntax#}1 << 8 == 256{#endsyntax#}</pre> 1370 </td> 1371 </tr> 1372 <tr> 1373 <td><pre>{#syntax#}a >> b 1374 a >>= b{#endsyntax#}</pre></td> 1375 <td> 1376 <ul> 1377 <li>{#link|Integers#}</li> 1378 </ul> 1379 </td> 1380 <td>Bit Shift Right. 1381 <ul> 1382 <li>{#syntax#}b{#endsyntax#} must be {#link|comptime-known|comptime#} or have a type with log2 number of bits as {#syntax#}a{#endsyntax#}.</li> 1383 <li>See also {#link|@shrExact#}.</li> 1384 </ul> 1385 </td> 1386 <td> 1387 <pre>{#syntax#}10 >> 1 == 5{#endsyntax#}</pre> 1388 </td> 1389 </tr> 1390 <tr> 1391 <td><pre>{#syntax#}a & b 1392 a &= b{#endsyntax#}</pre></td> 1393 <td> 1394 <ul> 1395 <li>{#link|Integers#}</li> 1396 </ul> 1397 </td> 1398 <td>Bitwise AND. 1399 <ul> 1400 <li>Invokes {#link|Peer Type Resolution#} for the operands.</li> 1401 </ul> 1402 </td> 1403 <td> 1404 <pre>{#syntax#}0b011 & 0b101 == 0b001{#endsyntax#}</pre> 1405 </td> 1406 </tr> 1407 <tr> 1408 <td><pre>{#syntax#}a | b 1409 a |= b{#endsyntax#}</pre></td> 1410 <td> 1411 <ul> 1412 <li>{#link|Integers#}</li> 1413 </ul> 1414 </td> 1415 <td>Bitwise OR. 1416 <ul> 1417 <li>Invokes {#link|Peer Type Resolution#} for the operands.</li> 1418 </ul> 1419 </td> 1420 <td> 1421 <pre>{#syntax#}0b010 | 0b100 == 0b110{#endsyntax#}</pre> 1422 </td> 1423 </tr> 1424 <tr> 1425 <td><pre>{#syntax#}a ^ b 1426 a ^= b{#endsyntax#}</pre></td> 1427 <td> 1428 <ul> 1429 <li>{#link|Integers#}</li> 1430 </ul> 1431 </td> 1432 <td>Bitwise XOR. 1433 <ul> 1434 <li>Invokes {#link|Peer Type Resolution#} for the operands.</li> 1435 </ul> 1436 </td> 1437 <td> 1438 <pre>{#syntax#}0b011 ^ 0b101 == 0b110{#endsyntax#}</pre> 1439 </td> 1440 </tr> 1441 <tr> 1442 <td><pre>{#syntax#}~a{#endsyntax#}</pre></td> 1443 <td> 1444 <ul> 1445 <li>{#link|Integers#}</li> 1446 </ul> 1447 </td> 1448 <td> 1449 Bitwise NOT. 1450 </td> 1451 <td> 1452 <pre>{#syntax#}~@as(u8, 0b10101111) == 0b01010000{#endsyntax#}</pre> 1453 </td> 1454 </tr> 1455 <tr> 1456 <td><pre>{#syntax#}a orelse b{#endsyntax#}</pre></td> 1457 <td> 1458 <ul> 1459 <li>{#link|Optionals#}</li> 1460 </ul> 1461 </td> 1462 <td>If {#syntax#}a{#endsyntax#} is {#syntax#}null{#endsyntax#}, 1463 returns {#syntax#}b{#endsyntax#} ("default value"), 1464 otherwise returns the unwrapped value of {#syntax#}a{#endsyntax#}. 1465 Note that {#syntax#}b{#endsyntax#} may be a value of type {#link|noreturn#}. 1466 </td> 1467 <td> 1468 <pre>{#syntax#}const value: ?u32 = null; 1469 const unwrapped = value orelse 1234; 1470 unwrapped == 1234{#endsyntax#}</pre> 1471 </td> 1472 </tr> 1473 <tr> 1474 <td><pre>{#syntax#}a.?{#endsyntax#}</pre></td> 1475 <td> 1476 <ul> 1477 <li>{#link|Optionals#}</li> 1478 </ul> 1479 </td> 1480 <td> 1481 Equivalent to: 1482 <pre>{#syntax#}a orelse unreachable{#endsyntax#}</pre> 1483 </td> 1484 <td> 1485 <pre>{#syntax#}const value: ?u32 = 5678; 1486 value.? == 5678{#endsyntax#}</pre> 1487 </td> 1488 </tr> 1489 <tr> 1490 <td><pre>{#syntax#}a catch b 1491 a catch |err| b{#endsyntax#}</pre></td> 1492 <td> 1493 <ul> 1494 <li>{#link|Error Unions|Errors#}</li> 1495 </ul> 1496 </td> 1497 <td>If {#syntax#}a{#endsyntax#} is an {#syntax#}error{#endsyntax#}, 1498 returns {#syntax#}b{#endsyntax#} ("default value"), 1499 otherwise returns the unwrapped value of {#syntax#}a{#endsyntax#}. 1500 Note that {#syntax#}b{#endsyntax#} may be a value of type {#link|noreturn#}. 1501 {#syntax#}err{#endsyntax#} is the {#syntax#}error{#endsyntax#} and is in scope of the expression {#syntax#}b{#endsyntax#}. 1502 </td> 1503 <td> 1504 <pre>{#syntax#}const value: anyerror!u32 = error.Broken; 1505 const unwrapped = value catch 1234; 1506 unwrapped == 1234{#endsyntax#}</pre> 1507 </td> 1508 </tr> 1509 <tr> 1510 <td><pre>{#syntax#}a and b{#endsyntax#}</pre></td> 1511 <td> 1512 <ul> 1513 <li>{#link|bool|Primitive Types#}</li> 1514 </ul> 1515 </td> 1516 <td> 1517 If {#syntax#}a{#endsyntax#} is {#syntax#}false{#endsyntax#}, returns {#syntax#}false{#endsyntax#} 1518 without evaluating {#syntax#}b{#endsyntax#}. Otherwise, returns {#syntax#}b{#endsyntax#}. 1519 </td> 1520 <td> 1521 <pre>{#syntax#}(false and true) == false{#endsyntax#}</pre> 1522 </td> 1523 </tr> 1524 <tr> 1525 <td><pre>{#syntax#}a or b{#endsyntax#}</pre></td> 1526 <td> 1527 <ul> 1528 <li>{#link|bool|Primitive Types#}</li> 1529 </ul> 1530 </td> 1531 <td> 1532 If {#syntax#}a{#endsyntax#} is {#syntax#}true{#endsyntax#}, returns {#syntax#}true{#endsyntax#} 1533 without evaluating {#syntax#}b{#endsyntax#}. Otherwise, returns {#syntax#}b{#endsyntax#}. 1534 </td> 1535 <td> 1536 <pre>{#syntax#}false or true == true{#endsyntax#}</pre> 1537 </td> 1538 </tr> 1539 <tr> 1540 <td><pre>{#syntax#}!a{#endsyntax#}</pre></td> 1541 <td> 1542 <ul> 1543 <li>{#link|bool|Primitive Types#}</li> 1544 </ul> 1545 </td> 1546 <td> 1547 Boolean NOT. 1548 </td> 1549 <td> 1550 <pre>{#syntax#}!false == true{#endsyntax#}</pre> 1551 </td> 1552 </tr> 1553 <tr> 1554 <td><pre>{#syntax#}a == b{#endsyntax#}</pre></td> 1555 <td> 1556 <ul> 1557 <li>{#link|Integers#}</li> 1558 <li>{#link|Floats#}</li> 1559 <li>{#link|bool|Primitive Types#}</li> 1560 <li>{#link|type|Primitive Types#}</li> 1561 </ul> 1562 </td> 1563 <td> 1564 Returns {#syntax#}true{#endsyntax#} if a and b are equal, otherwise returns {#syntax#}false{#endsyntax#}. 1565 Invokes {#link|Peer Type Resolution#} for the operands. 1566 </td> 1567 <td> 1568 <pre>{#syntax#}(1 == 1) == true{#endsyntax#}</pre> 1569 </td> 1570 </tr> 1571 <tr> 1572 <td><pre>{#syntax#}a == null{#endsyntax#}</pre></td> 1573 <td> 1574 <ul> 1575 <li>{#link|Optionals#}</li> 1576 </ul> 1577 </td> 1578 <td> 1579 Returns {#syntax#}true{#endsyntax#} if a is {#syntax#}null{#endsyntax#}, otherwise returns {#syntax#}false{#endsyntax#}. 1580 </td> 1581 <td> 1582 <pre>{#syntax#}const value: ?u32 = null; 1583 value == null{#endsyntax#}</pre> 1584 </td> 1585 </tr> 1586 <tr> 1587 <td><pre>{#syntax#}a != b{#endsyntax#}</pre></td> 1588 <td> 1589 <ul> 1590 <li>{#link|Integers#}</li> 1591 <li>{#link|Floats#}</li> 1592 <li>{#link|bool|Primitive Types#}</li> 1593 <li>{#link|type|Primitive Types#}</li> 1594 </ul> 1595 </td> 1596 <td> 1597 Returns {#syntax#}false{#endsyntax#} if a and b are equal, otherwise returns {#syntax#}true{#endsyntax#}. 1598 Invokes {#link|Peer Type Resolution#} for the operands. 1599 </td> 1600 <td> 1601 <pre>{#syntax#}(1 != 1) == false{#endsyntax#}</pre> 1602 </td> 1603 </tr> 1604 <tr> 1605 <td><pre>{#syntax#}a > b{#endsyntax#}</pre></td> 1606 <td> 1607 <ul> 1608 <li>{#link|Integers#}</li> 1609 <li>{#link|Floats#}</li> 1610 </ul> 1611 </td> 1612 <td> 1613 Returns {#syntax#}true{#endsyntax#} if a is greater than b, otherwise returns {#syntax#}false{#endsyntax#}. 1614 Invokes {#link|Peer Type Resolution#} for the operands. 1615 </td> 1616 <td> 1617 <pre>{#syntax#}(2 > 1) == true{#endsyntax#}</pre> 1618 </td> 1619 </tr> 1620 <tr> 1621 <td><pre>{#syntax#}a >= b{#endsyntax#}</pre></td> 1622 <td> 1623 <ul> 1624 <li>{#link|Integers#}</li> 1625 <li>{#link|Floats#}</li> 1626 </ul> 1627 </td> 1628 <td> 1629 Returns {#syntax#}true{#endsyntax#} if a is greater than or equal to b, otherwise returns {#syntax#}false{#endsyntax#}. 1630 Invokes {#link|Peer Type Resolution#} for the operands. 1631 </td> 1632 <td> 1633 <pre>{#syntax#}(2 >= 1) == true{#endsyntax#}</pre> 1634 </td> 1635 </tr> 1636 <tr> 1637 <td><pre>{#syntax#}a < b{#endsyntax#}</pre></td> 1638 <td> 1639 <ul> 1640 <li>{#link|Integers#}</li> 1641 <li>{#link|Floats#}</li> 1642 </ul> 1643 </td> 1644 <td> 1645 Returns {#syntax#}true{#endsyntax#} if a is less than b, otherwise returns {#syntax#}false{#endsyntax#}. 1646 Invokes {#link|Peer Type Resolution#} for the operands. 1647 </td> 1648 <td> 1649 <pre>{#syntax#}(1 < 2) == true{#endsyntax#}></pre> 1650 </td> 1651 </tr> 1652 <tr> 1653 <td><pre>{#syntax#}a <= b{#endsyntax#}</pre></td> 1654 <td> 1655 <ul> 1656 <li>{#link|Integers#}</li> 1657 <li>{#link|Floats#}</li> 1658 </ul> 1659 </td> 1660 <td> 1661 Returns {#syntax#}true{#endsyntax#} if a is less than or equal to b, otherwise returns {#syntax#}false{#endsyntax#}. 1662 Invokes {#link|Peer Type Resolution#} for the operands. 1663 </td> 1664 <td> 1665 <pre>{#syntax#}(1 <= 2) == true{#endsyntax#}</pre> 1666 </td> 1667 </tr> 1668 <tr> 1669 <td><pre>{#syntax#}a ++ b{#endsyntax#}</pre></td> 1670 <td> 1671 <ul> 1672 <li>{#link|Arrays#}</li> 1673 </ul> 1674 </td> 1675 <td> 1676 Array concatenation. 1677 <ul> 1678 <li>Only available when {#syntax#}a{#endsyntax#} and {#syntax#}b{#endsyntax#} are {#link|compile-time known|comptime#}. 1679 </ul> 1680 </td> 1681 <td> 1682 <pre>{#syntax#}const mem = @import("std").mem; 1683 const array1 = [_]u32{1,2}; 1684 const array2 = [_]u32{3,4}; 1685 const together = array1 ++ array2; 1686 mem.eql(u32, &together, &[_]u32{1,2,3,4}){#endsyntax#}</pre> 1687 </td> 1688 </tr> 1689 <tr> 1690 <td><pre>{#syntax#}a ** b{#endsyntax#}</pre></td> 1691 <td> 1692 <ul> 1693 <li>{#link|Arrays#}</li> 1694 </ul> 1695 </td> 1696 <td> 1697 Array multiplication. 1698 <ul> 1699 <li>Only available when {#syntax#}a{#endsyntax#} and {#syntax#}b{#endsyntax#} are {#link|compile-time known|comptime#}. 1700 </ul> 1701 </td> 1702 <td> 1703 <pre>{#syntax#}const mem = @import("std").mem; 1704 const pattern = "ab" ** 3; 1705 mem.eql(u8, pattern, "ababab"){#endsyntax#}</pre> 1706 </td> 1707 </tr> 1708 <tr> 1709 <td><pre>{#syntax#}a.*{#endsyntax#}</pre></td> 1710 <td> 1711 <ul> 1712 <li>{#link|Pointers#}</li> 1713 </ul> 1714 </td> 1715 <td> 1716 Pointer dereference. 1717 </td> 1718 <td> 1719 <pre>{#syntax#}const x: u32 = 1234; 1720 const ptr = &x; 1721 ptr.* == 1234{#endsyntax#}</pre> 1722 </td> 1723 </tr> 1724 <tr> 1725 <td><pre>{#syntax#}&a{#endsyntax#}</pre></td> 1726 <td> 1727 All types 1728 </td> 1729 <td> 1730 Address of. 1731 </td> 1732 <td> 1733 <pre>{#syntax#}const x: u32 = 1234; 1734 const ptr = &x; 1735 ptr.* == 1234{#endsyntax#}</pre> 1736 </td> 1737 </tr> 1738 <tr> 1739 <td><pre>{#syntax#}a || b{#endsyntax#}</pre></td> 1740 <td> 1741 <ul> 1742 <li>{#link|Error Set Type#}</li> 1743 </ul> 1744 </td> 1745 <td> 1746 {#link|Merging Error Sets#} 1747 </td> 1748 <td> 1749 <pre>{#syntax#}const A = error{One}; 1750 const B = error{Two}; 1751 (A || B) == error{One, Two}{#endsyntax#}</pre> 1752 </td> 1753 </tr> 1754 </table> 1755 </div> 1756 {#header_close#} 1757 {#header_open|Precedence#} 1758 <pre>{#syntax#}x() x[] x.y x.* x.? 1759 a!b 1760 x{} 1761 !x -x -%x ~x &x ?x 1762 * / % ** *% || 1763 + - ++ +% -% 1764 << >> 1765 & ^ | orelse catch 1766 == != < > <= >= 1767 and 1768 or 1769 = *= /= %= += -= <<= >>= &= ^= |={#endsyntax#}</pre> 1770 {#header_close#} 1771 {#header_close#} 1772 {#header_open|Arrays#} 1773 {#code_begin|test|arrays#} 1774 const expect = @import("std").testing.expect; 1775 const assert = @import("std").debug.assert; 1776 const mem = @import("std").mem; 1777 1778 // array literal 1779 const message = [_]u8{ 'h', 'e', 'l', 'l', 'o' }; 1780 1781 // get the size of an array 1782 comptime { 1783 assert(message.len == 5); 1784 } 1785 1786 // A string literal is a single-item pointer to an array literal. 1787 const same_message = "hello"; 1788 1789 comptime { 1790 assert(mem.eql(u8, &message, same_message)); 1791 } 1792 1793 test "iterate over an array" { 1794 var sum: usize = 0; 1795 for (message) |byte| { 1796 sum += byte; 1797 } 1798 try expect(sum == 'h' + 'e' + 'l' * 2 + 'o'); 1799 } 1800 1801 // modifiable array 1802 var some_integers: [100]i32 = undefined; 1803 1804 test "modify an array" { 1805 for (some_integers) |*item, i| { 1806 item.* = @intCast(i32, i); 1807 } 1808 try expect(some_integers[10] == 10); 1809 try expect(some_integers[99] == 99); 1810 } 1811 1812 // array concatenation works if the values are known 1813 // at compile time 1814 const part_one = [_]i32{ 1, 2, 3, 4 }; 1815 const part_two = [_]i32{ 5, 6, 7, 8 }; 1816 const all_of_it = part_one ++ part_two; 1817 comptime { 1818 assert(mem.eql(i32, &all_of_it, &[_]i32{ 1, 2, 3, 4, 5, 6, 7, 8 })); 1819 } 1820 1821 // remember that string literals are arrays 1822 const hello = "hello"; 1823 const world = "world"; 1824 const hello_world = hello ++ " " ++ world; 1825 comptime { 1826 assert(mem.eql(u8, hello_world, "hello world")); 1827 } 1828 1829 // ** does repeating patterns 1830 const pattern = "ab" ** 3; 1831 comptime { 1832 assert(mem.eql(u8, pattern, "ababab")); 1833 } 1834 1835 // initialize an array to zero 1836 const all_zero = [_]u16{0} ** 10; 1837 1838 comptime { 1839 assert(all_zero.len == 10); 1840 assert(all_zero[5] == 0); 1841 } 1842 1843 // use compile-time code to initialize an array 1844 var fancy_array = init: { 1845 var initial_value: [10]Point = undefined; 1846 for (initial_value) |*pt, i| { 1847 pt.* = Point{ 1848 .x = @intCast(i32, i), 1849 .y = @intCast(i32, i) * 2, 1850 }; 1851 } 1852 break :init initial_value; 1853 }; 1854 const Point = struct { 1855 x: i32, 1856 y: i32, 1857 }; 1858 1859 test "compile-time array initialization" { 1860 try expect(fancy_array[4].x == 4); 1861 try expect(fancy_array[4].y == 8); 1862 } 1863 1864 // call a function to initialize an array 1865 var more_points = [_]Point{makePoint(3)} ** 10; 1866 fn makePoint(x: i32) Point { 1867 return Point{ 1868 .x = x, 1869 .y = x * 2, 1870 }; 1871 } 1872 test "array initialization with function calls" { 1873 try expect(more_points[4].x == 3); 1874 try expect(more_points[4].y == 6); 1875 try expect(more_points.len == 10); 1876 } 1877 {#code_end#} 1878 {#see_also|for|Slices#} 1879 1880 {#header_open|Anonymous List Literals#} 1881 <p>Similar to {#link|Enum Literals#} and {#link|Anonymous Struct Literals#} 1882 the type can be omitted from array literals:</p> 1883 {#code_begin|test|anon_list#} 1884 const std = @import("std"); 1885 const expect = std.testing.expect; 1886 1887 test "anonymous list literal syntax" { 1888 var array: [4]u8 = .{11, 22, 33, 44}; 1889 try expect(array[0] == 11); 1890 try expect(array[1] == 22); 1891 try expect(array[2] == 33); 1892 try expect(array[3] == 44); 1893 } 1894 {#code_end#} 1895 <p> 1896 If there is no type in the result location then an anonymous list literal actually 1897 turns into a {#link|struct#} with numbered field names: 1898 </p> 1899 {#code_begin|test|infer_list_literal#} 1900 const std = @import("std"); 1901 const expect = std.testing.expect; 1902 1903 test "fully anonymous list literal" { 1904 try dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi"}); 1905 } 1906 1907 fn dump(args: anytype) !void { 1908 try expect(args.@"0" == 1234); 1909 try expect(args.@"1" == 12.34); 1910 try expect(args.@"2"); 1911 try expect(args.@"3"[0] == 'h'); 1912 try expect(args.@"3"[1] == 'i'); 1913 } 1914 {#code_end#} 1915 {#header_close#} 1916 1917 {#header_open|Multidimensional Arrays#} 1918 <p> 1919 Mutlidimensional arrays can be created by nesting arrays: 1920 </p> 1921 {#code_begin|test|multidimensional#} 1922 const std = @import("std"); 1923 const expect = std.testing.expect; 1924 1925 const mat4x4 = [4][4]f32{ 1926 [_]f32{ 1.0, 0.0, 0.0, 0.0 }, 1927 [_]f32{ 0.0, 1.0, 0.0, 1.0 }, 1928 [_]f32{ 0.0, 0.0, 1.0, 0.0 }, 1929 [_]f32{ 0.0, 0.0, 0.0, 1.0 }, 1930 }; 1931 test "multidimensional arrays" { 1932 // Access the 2D array by indexing the outer array, and then the inner array. 1933 try expect(mat4x4[1][1] == 1.0); 1934 1935 // Here we iterate with for loops. 1936 for (mat4x4) |row, row_index| { 1937 for (row) |cell, column_index| { 1938 if (row_index == column_index) { 1939 try expect(cell == 1.0); 1940 } 1941 } 1942 } 1943 } 1944 {#code_end#} 1945 {#header_close#} 1946 1947 {#header_open|Sentinel-Terminated Arrays#} 1948 <p> 1949 The syntax {#syntax#}[N:x]T{#endsyntax#} describes an array which has a sentinel element of value {#syntax#}x{#endsyntax#} at the 1950 index corresponding to {#syntax#}len{#endsyntax#}. 1951 </p> 1952 {#code_begin|test|null_terminated_array#} 1953 const std = @import("std"); 1954 const expect = std.testing.expect; 1955 1956 test "null terminated array" { 1957 const array = [_:0]u8 {1, 2, 3, 4}; 1958 1959 try expect(@TypeOf(array) == [4:0]u8); 1960 try expect(array.len == 4); 1961 try expect(array[4] == 0); 1962 } 1963 {#code_end#} 1964 {#see_also|Sentinel-Terminated Pointers|Sentinel-Terminated Slices#} 1965 {#header_close#} 1966 {#header_close#} 1967 1968 {#header_open|Vectors#} 1969 <p> 1970 A vector is a group of booleans, {#link|Integers#}, {#link|Floats#}, or {#link|Pointers#} which are operated on 1971 in parallel using a single instruction ({#link|SIMD#}). Vector types are created with the builtin function {#link|@Type#}, 1972 or using the shorthand as {#syntax#}std.meta.Vector{#endsyntax#}. 1973 </p> 1974 <p> 1975 TODO talk about C ABI interop 1976 </p> 1977 {#header_open|SIMD#} 1978 <p> 1979 TODO Zig's SIMD abilities are just beginning to be fleshed out. Here are some talking points to update the 1980 docs with: 1981 * What kind of operations can you do? All the operations on integers and floats? What about mixing scalar and vector? 1982 * How to convert to/from vectors/arrays 1983 * How to access individual elements from vectors, how to loop over the elements 1984 * "shuffle" 1985 * Advice on writing high perf software, how to abstract the best way 1986 </p> 1987 {#header_close#} 1988 {#header_close#} 1989 1990 {#header_open|Pointers#} 1991 <p> 1992 Zig has two kinds of pointers: single-item and many-item. 1993 </p> 1994 <ul> 1995 <li>{#syntax#}*T{#endsyntax#} - single-item pointer to exactly one item. 1996 <ul> 1997 <li>Supports deref syntax: {#syntax#}ptr.*{#endsyntax#}</li> 1998 </ul> 1999 </li> 2000 <li>{#syntax#}[*]T{#endsyntax#} - many-item pointer to unknown number of items. 2001 <ul> 2002 <li>Supports index syntax: {#syntax#}ptr[i]{#endsyntax#}</li> 2003 <li>Supports slice syntax: {#syntax#}ptr[start..end]{#endsyntax#}</li> 2004 <li>Supports pointer arithmetic: {#syntax#}ptr + x{#endsyntax#}, {#syntax#}ptr - x{#endsyntax#}</li> 2005 <li>{#syntax#}T{#endsyntax#} must have a known size, which means that it cannot be 2006 {#syntax#}c_void{#endsyntax#} or any other {#link|opaque type|opaque#}.</li> 2007 </ul> 2008 </li> 2009 </ul> 2010 <p>These types are closely related to {#link|Arrays#} and {#link|Slices#}:</p> 2011 <ul> 2012 <li>{#syntax#}*[N]T{#endsyntax#} - pointer to N items, same as single-item pointer to an array. 2013 <ul> 2014 <li>Supports index syntax: {#syntax#}array_ptr[i]{#endsyntax#}</li> 2015 <li>Supports slice syntax: {#syntax#}array_ptr[start..end]{#endsyntax#}</li> 2016 <li>Supports len property: {#syntax#}array_ptr.len{#endsyntax#}</li> 2017 </ul> 2018 </li> 2019 </ul> 2020 <ul> 2021 <li>{#syntax#}[]T{#endsyntax#} - pointer to runtime-known number of items. 2022 <ul> 2023 <li>Supports index syntax: {#syntax#}slice[i]{#endsyntax#}</li> 2024 <li>Supports slice syntax: {#syntax#}slice[start..end]{#endsyntax#}</li> 2025 <li>Supports len property: {#syntax#}slice.len{#endsyntax#}</li> 2026 </ul> 2027 </li> 2028 </ul> 2029 <p>Use {#syntax#}&x{#endsyntax#} to obtain a single-item pointer:</p> 2030 {#code_begin|test#} 2031 const expect = @import("std").testing.expect; 2032 2033 test "address of syntax" { 2034 // Get the address of a variable: 2035 const x: i32 = 1234; 2036 const x_ptr = &x; 2037 2038 // Dereference a pointer: 2039 try expect(x_ptr.* == 1234); 2040 2041 // When you get the address of a const variable, you get a const single-item pointer. 2042 try expect(@TypeOf(x_ptr) == *const i32); 2043 2044 // If you want to mutate the value, you'd need an address of a mutable variable: 2045 var y: i32 = 5678; 2046 const y_ptr = &y; 2047 try expect(@TypeOf(y_ptr) == *i32); 2048 y_ptr.* += 1; 2049 try expect(y_ptr.* == 5679); 2050 } 2051 2052 test "pointer array access" { 2053 // Taking an address of an individual element gives a 2054 // single-item pointer. This kind of pointer 2055 // does not support pointer arithmetic. 2056 var array = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 2057 const ptr = &array[2]; 2058 try expect(@TypeOf(ptr) == *u8); 2059 2060 try expect(array[2] == 3); 2061 ptr.* += 1; 2062 try expect(array[2] == 4); 2063 } 2064 {#code_end#} 2065 <p> 2066 In Zig, we generally prefer {#link|Slices#} rather than {#link|Sentinel-Terminated Pointers#}. 2067 You can turn an array or pointer into a slice using slice syntax. 2068 </p> 2069 <p> 2070 Slices have bounds checking and are therefore protected 2071 against this kind of undefined behavior. This is one reason 2072 we prefer slices to pointers. 2073 </p> 2074 {#code_begin|test#} 2075 const expect = @import("std").testing.expect; 2076 2077 test "pointer slicing" { 2078 var array = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 2079 const slice = array[2..4]; 2080 try expect(slice.len == 2); 2081 2082 try expect(array[3] == 4); 2083 slice[1] += 1; 2084 try expect(array[3] == 5); 2085 } 2086 {#code_end#} 2087 <p>Pointers work at compile-time too, as long as the code does not depend on 2088 an undefined memory layout:</p> 2089 {#code_begin|test#} 2090 const expect = @import("std").testing.expect; 2091 2092 test "comptime pointers" { 2093 comptime { 2094 var x: i32 = 1; 2095 const ptr = &x; 2096 ptr.* += 1; 2097 x += 1; 2098 try expect(ptr.* == 3); 2099 } 2100 } 2101 {#code_end#} 2102 <p>To convert an integer address into a pointer, use {#syntax#}@intToPtr{#endsyntax#}. 2103 To convert a pointer to an integer, use {#syntax#}@ptrToInt{#endsyntax#}:</p> 2104 {#code_begin|test#} 2105 const expect = @import("std").testing.expect; 2106 2107 test "@ptrToInt and @intToPtr" { 2108 const ptr = @intToPtr(*i32, 0xdeadbee0); 2109 const addr = @ptrToInt(ptr); 2110 try expect(@TypeOf(addr) == usize); 2111 try expect(addr == 0xdeadbee0); 2112 } 2113 {#code_end#} 2114 <p>Zig is able to preserve memory addresses in comptime code, as long as 2115 the pointer is never dereferenced:</p> 2116 {#code_begin|test#} 2117 const expect = @import("std").testing.expect; 2118 2119 test "comptime @intToPtr" { 2120 comptime { 2121 // Zig is able to do this at compile-time, as long as 2122 // ptr is never dereferenced. 2123 const ptr = @intToPtr(*i32, 0xdeadbee0); 2124 const addr = @ptrToInt(ptr); 2125 try expect(@TypeOf(addr) == usize); 2126 try expect(addr == 0xdeadbee0); 2127 } 2128 } 2129 {#code_end#} 2130 {#see_also|Optional Pointers|@intToPtr|@ptrToInt|C Pointers|Pointers to Zero Bit Types#} 2131 {#header_open|volatile#} 2132 <p>Loads and stores are assumed to not have side effects. If a given load or store 2133 should have side effects, such as Memory Mapped Input/Output (MMIO), use {#syntax#}volatile{#endsyntax#}. 2134 In the following code, loads and stores with {#syntax#}mmio_ptr{#endsyntax#} are guaranteed to all happen 2135 and in the same order as in source code:</p> 2136 {#code_begin|test#} 2137 const expect = @import("std").testing.expect; 2138 2139 test "volatile" { 2140 const mmio_ptr = @intToPtr(*volatile u8, 0x12345678); 2141 try expect(@TypeOf(mmio_ptr) == *volatile u8); 2142 } 2143 {#code_end#} 2144 <p> 2145 Note that {#syntax#}volatile{#endsyntax#} is unrelated to concurrency and {#link|Atomics#}. 2146 If you see code that is using {#syntax#}volatile{#endsyntax#} for something other than Memory Mapped 2147 Input/Output, it is probably a bug. 2148 </p> 2149 {#header_close#} 2150 <p> 2151 To convert one pointer type to another, use {#link|@ptrCast#}. This is an unsafe 2152 operation that Zig cannot protect you against. Use {#syntax#}@ptrCast{#endsyntax#} only when other 2153 conversions are not possible. 2154 </p> 2155 {#code_begin|test#} 2156 const std = @import("std"); 2157 const expect = std.testing.expect; 2158 2159 test "pointer casting" { 2160 const bytes align(@alignOf(u32)) = [_]u8{ 0x12, 0x12, 0x12, 0x12 }; 2161 const u32_ptr = @ptrCast(*const u32, &bytes); 2162 try expect(u32_ptr.* == 0x12121212); 2163 2164 // Even this example is contrived - there are better ways to do the above than 2165 // pointer casting. For example, using a slice narrowing cast: 2166 const u32_value = std.mem.bytesAsSlice(u32, bytes[0..])[0]; 2167 try expect(u32_value == 0x12121212); 2168 2169 // And even another way, the most straightforward way to do it: 2170 try expect(@bitCast(u32, bytes) == 0x12121212); 2171 } 2172 2173 test "pointer child type" { 2174 // pointer types have a `child` field which tells you the type they point to. 2175 try expect(@typeInfo(*u32).Pointer.child == u32); 2176 } 2177 {#code_end#} 2178 {#header_open|Alignment#} 2179 <p> 2180 Each type has an <strong>alignment</strong> - a number of bytes such that, 2181 when a value of the type is loaded from or stored to memory, 2182 the memory address must be evenly divisible by this number. You can use 2183 {#link|@alignOf#} to find out this value for any type. 2184 </p> 2185 <p> 2186 Alignment depends on the CPU architecture, but is always a power of two, and 2187 less than {#syntax#}1 << 29{#endsyntax#}. 2188 </p> 2189 <p> 2190 In Zig, a pointer type has an alignment value. If the value is equal to the 2191 alignment of the underlying type, it can be omitted from the type: 2192 </p> 2193 {#code_begin|test#} 2194 const std = @import("std"); 2195 const expect = std.testing.expect; 2196 2197 test "variable alignment" { 2198 var x: i32 = 1234; 2199 const align_of_i32 = @alignOf(@TypeOf(x)); 2200 try expect(@TypeOf(&x) == *i32); 2201 try expect(*i32 == *align(align_of_i32) i32); 2202 if (std.Target.current.cpu.arch == .x86_64) { 2203 try expect(@typeInfo(*i32).Pointer.alignment == 4); 2204 } 2205 } 2206 {#code_end#} 2207 <p>In the same way that a {#syntax#}*i32{#endsyntax#} can be {#link|coerced|Type Coercion#} to a 2208 {#syntax#}*const i32{#endsyntax#}, a pointer with a larger alignment can be implicitly 2209 cast to a pointer with a smaller alignment, but not vice versa. 2210 </p> 2211 <p> 2212 You can specify alignment on variables and functions. If you do this, then 2213 pointers to them get the specified alignment: 2214 </p> 2215 {#code_begin|test#} 2216 const expect = @import("std").testing.expect; 2217 2218 var foo: u8 align(4) = 100; 2219 2220 test "global variable alignment" { 2221 try expect(@typeInfo(@TypeOf(&foo)).Pointer.alignment == 4); 2222 try expect(@TypeOf(&foo) == *align(4) u8); 2223 const as_pointer_to_array: *[1]u8 = &foo; 2224 const as_slice: []u8 = as_pointer_to_array; 2225 try expect(@TypeOf(as_slice) == []align(4) u8); 2226 } 2227 2228 fn derp() align(@sizeOf(usize) * 2) i32 { return 1234; } 2229 fn noop1() align(1) void {} 2230 fn noop4() align(4) void {} 2231 2232 test "function alignment" { 2233 try expect(derp() == 1234); 2234 try expect(@TypeOf(noop1) == fn() align(1) void); 2235 try expect(@TypeOf(noop4) == fn() align(4) void); 2236 noop1(); 2237 noop4(); 2238 } 2239 {#code_end#} 2240 <p> 2241 If you have a pointer or a slice that has a small alignment, but you know that it actually 2242 has a bigger alignment, use {#link|@alignCast#} to change the 2243 pointer into a more aligned pointer. This is a no-op at runtime, but inserts a 2244 {#link|safety check|Incorrect Pointer Alignment#}: 2245 </p> 2246 {#code_begin|test_safety|incorrect alignment#} 2247 const std = @import("std"); 2248 2249 test "pointer alignment safety" { 2250 var array align(4) = [_]u32{ 0x11111111, 0x11111111 }; 2251 const bytes = std.mem.sliceAsBytes(array[0..]); 2252 try std.testing.expect(foo(bytes) == 0x11111111); 2253 } 2254 fn foo(bytes: []u8) u32 { 2255 const slice4 = bytes[1..5]; 2256 const int_slice = std.mem.bytesAsSlice(u32, @alignCast(4, slice4)); 2257 return int_slice[0]; 2258 } 2259 {#code_end#} 2260 {#header_close#} 2261 2262 {#header_open|allowzero#} 2263 <p> 2264 This pointer attribute allows a pointer to have address zero. This is only ever needed on the 2265 freestanding OS target, where the address zero is mappable. If you want to represent null pointers, use 2266 {#link|Optional Pointers#} instead. {#link|Optional Pointers#} with {#syntax#}allowzero{#endsyntax#} 2267 are not the same size as pointers. In this code example, if the pointer 2268 did not have the {#syntax#}allowzero{#endsyntax#} attribute, this would be a 2269 {#link|Pointer Cast Invalid Null#} panic: 2270 </p> 2271 {#code_begin|test|allowzero#} 2272 const std = @import("std"); 2273 const expect = std.testing.expect; 2274 2275 test "allowzero" { 2276 var zero: usize = 0; 2277 var ptr = @intToPtr(*allowzero i32, zero); 2278 try expect(@ptrToInt(ptr) == 0); 2279 } 2280 {#code_end#} 2281 {#header_close#} 2282 2283 {#header_open|Sentinel-Terminated Pointers#} 2284 <p> 2285 The syntax {#syntax#}[*:x]T{#endsyntax#} describes a pointer that 2286 has a length determined by a sentinel value. This provides protection 2287 against buffer overflow and overreads. 2288 </p> 2289 {#code_begin|exe_build_err#} 2290 {#link_libc#} 2291 const std = @import("std"); 2292 2293 // This is also available as `std.c.printf`. 2294 pub extern "c" fn printf(format: [*:0]const u8, ...) c_int; 2295 2296 pub fn main() anyerror!void { 2297 _ = printf("Hello, world!\n"); // OK 2298 2299 const msg = "Hello, world!\n"; 2300 const non_null_terminated_msg: [msg.len]u8 = msg.*; 2301 _ = printf(&non_null_terminated_msg); 2302 } 2303 {#code_end#} 2304 {#see_also|Sentinel-Terminated Slices|Sentinel-Terminated Arrays#} 2305 {#header_close#} 2306 {#header_close#} 2307 2308 {#header_open|Slices#} 2309 {#code_begin|test_safety|index out of bounds#} 2310 const expect = @import("std").testing.expect; 2311 2312 test "basic slices" { 2313 var array = [_]i32{ 1, 2, 3, 4 }; 2314 // A slice is a pointer and a length. The difference between an array and 2315 // a slice is that the array's length is part of the type and known at 2316 // compile-time, whereas the slice's length is known at runtime. 2317 // Both can be accessed with the `len` field. 2318 var known_at_runtime_zero: usize = 0; 2319 const slice = array[known_at_runtime_zero..array.len]; 2320 try expect(&slice[0] == &array[0]); 2321 try expect(slice.len == array.len); 2322 2323 // Using the address-of operator on a slice gives a single-item pointer, 2324 // while using the `ptr` field gives a many-item pointer. 2325 try expect(@TypeOf(slice.ptr) == [*]i32); 2326 try expect(@TypeOf(&slice[0]) == *i32); 2327 try expect(@ptrToInt(slice.ptr) == @ptrToInt(&slice[0])); 2328 2329 // Slices have array bounds checking. If you try to access something out 2330 // of bounds, you'll get a safety check failure: 2331 slice[10] += 1; 2332 2333 // Note that `slice.ptr` does not invoke safety checking, while `&slice[0]` 2334 // asserts that the slice has len >= 1. 2335 } 2336 {#code_end#} 2337 <p>This is one reason we prefer slices to pointers.</p> 2338 {#code_begin|test|slices#} 2339 const std = @import("std"); 2340 const expect = std.testing.expect; 2341 const mem = std.mem; 2342 const fmt = std.fmt; 2343 2344 test "using slices for strings" { 2345 // Zig has no concept of strings. String literals are const pointers 2346 // to null-terminated arrays of u8, and by convention parameters 2347 // that are "strings" are expected to be UTF-8 encoded slices of u8. 2348 // Here we coerce *const [5:0]u8 and *const [6:0]u8 to []const u8 2349 const hello: []const u8 = "hello"; 2350 const world: []const u8 = "世界"; 2351 2352 var all_together: [100]u8 = undefined; 2353 // You can use slice syntax on an array to convert an array into a slice. 2354 const all_together_slice = all_together[0..]; 2355 // String concatenation example. 2356 const hello_world = try fmt.bufPrint(all_together_slice, "{s} {s}", .{ hello, world }); 2357 2358 // Generally, you can use UTF-8 and not worry about whether something is a 2359 // string. If you don't need to deal with individual characters, no need 2360 // to decode. 2361 try expect(mem.eql(u8, hello_world, "hello 世界")); 2362 } 2363 2364 test "slice pointer" { 2365 var array: [10]u8 = undefined; 2366 const ptr = &array; 2367 2368 // You can use slicing syntax to convert a pointer into a slice: 2369 const slice = ptr[0..5]; 2370 slice[2] = 3; 2371 try expect(slice[2] == 3); 2372 // The slice is mutable because we sliced a mutable pointer. 2373 // Furthermore, it is actually a pointer to an array, since the start 2374 // and end indexes were both comptime-known. 2375 try expect(@TypeOf(slice) == *[5]u8); 2376 2377 // You can also slice a slice: 2378 const slice2 = slice[2..3]; 2379 try expect(slice2.len == 1); 2380 try expect(slice2[0] == 3); 2381 } 2382 {#code_end#} 2383 {#see_also|Pointers|for|Arrays#} 2384 2385 {#header_open|Sentinel-Terminated Slices#} 2386 <p> 2387 The syntax {#syntax#}[:x]T{#endsyntax#} is a slice which has a runtime known length 2388 and also guarantees a sentinel value at the element indexed by the length. The type does not 2389 guarantee that there are no sentinel elements before that. Sentinel-terminated slices allow element 2390 access to the {#syntax#}len{#endsyntax#} index. 2391 </p> 2392 {#code_begin|test|null_terminated_slice#} 2393 const std = @import("std"); 2394 const expect = std.testing.expect; 2395 2396 test "null terminated slice" { 2397 const slice: [:0]const u8 = "hello"; 2398 2399 try expect(slice.len == 5); 2400 try expect(slice[5] == 0); 2401 } 2402 {#code_end#} 2403 {#see_also|Sentinel-Terminated Pointers|Sentinel-Terminated Arrays#} 2404 {#header_close#} 2405 {#header_close#} 2406 2407 {#header_open|struct#} 2408 {#code_begin|test|structs#} 2409 // Declare a struct. 2410 // Zig gives no guarantees about the order of fields and the size of 2411 // the struct but the fields are guaranteed to be ABI-aligned. 2412 const Point = struct { 2413 x: f32, 2414 y: f32, 2415 }; 2416 2417 // Maybe we want to pass it to OpenGL so we want to be particular about 2418 // how the bytes are arranged. 2419 const Point2 = packed struct { 2420 x: f32, 2421 y: f32, 2422 }; 2423 2424 2425 // Declare an instance of a struct. 2426 const p = Point { 2427 .x = 0.12, 2428 .y = 0.34, 2429 }; 2430 2431 // Maybe we're not ready to fill out some of the fields. 2432 var p2 = Point { 2433 .x = 0.12, 2434 .y = undefined, 2435 }; 2436 2437 // Structs can have methods 2438 // Struct methods are not special, they are only namespaced 2439 // functions that you can call with dot syntax. 2440 const Vec3 = struct { 2441 x: f32, 2442 y: f32, 2443 z: f32, 2444 2445 pub fn init(x: f32, y: f32, z: f32) Vec3 { 2446 return Vec3 { 2447 .x = x, 2448 .y = y, 2449 .z = z, 2450 }; 2451 } 2452 2453 pub fn dot(self: Vec3, other: Vec3) f32 { 2454 return self.x * other.x + self.y * other.y + self.z * other.z; 2455 } 2456 }; 2457 2458 const expect = @import("std").testing.expect; 2459 test "dot product" { 2460 const v1 = Vec3.init(1.0, 0.0, 0.0); 2461 const v2 = Vec3.init(0.0, 1.0, 0.0); 2462 try expect(v1.dot(v2) == 0.0); 2463 2464 // Other than being available to call with dot syntax, struct methods are 2465 // not special. You can reference them as any other declaration inside 2466 // the struct: 2467 try expect(Vec3.dot(v1, v2) == 0.0); 2468 } 2469 2470 // Structs can have global declarations. 2471 // Structs can have 0 fields. 2472 const Empty = struct { 2473 pub const PI = 3.14; 2474 }; 2475 test "struct namespaced variable" { 2476 try expect(Empty.PI == 3.14); 2477 try expect(@sizeOf(Empty) == 0); 2478 2479 // you can still instantiate an empty struct 2480 const does_nothing = Empty {}; 2481 } 2482 2483 // struct field order is determined by the compiler for optimal performance. 2484 // however, you can still calculate a struct base pointer given a field pointer: 2485 fn setYBasedOnX(x: *f32, y: f32) void { 2486 const point = @fieldParentPtr(Point, "x", x); 2487 point.y = y; 2488 } 2489 test "field parent pointer" { 2490 var point = Point { 2491 .x = 0.1234, 2492 .y = 0.5678, 2493 }; 2494 setYBasedOnX(&point.x, 0.9); 2495 try expect(point.y == 0.9); 2496 } 2497 2498 // You can return a struct from a function. This is how we do generics 2499 // in Zig: 2500 fn LinkedList(comptime T: type) type { 2501 return struct { 2502 pub const Node = struct { 2503 prev: ?*Node, 2504 next: ?*Node, 2505 data: T, 2506 }; 2507 2508 first: ?*Node, 2509 last: ?*Node, 2510 len: usize, 2511 }; 2512 } 2513 2514 test "linked list" { 2515 // Functions called at compile-time are memoized. This means you can 2516 // do this: 2517 try expect(LinkedList(i32) == LinkedList(i32)); 2518 2519 var list = LinkedList(i32) { 2520 .first = null, 2521 .last = null, 2522 .len = 0, 2523 }; 2524 try expect(list.len == 0); 2525 2526 // Since types are first class values you can instantiate the type 2527 // by assigning it to a variable: 2528 const ListOfInts = LinkedList(i32); 2529 try expect(ListOfInts == LinkedList(i32)); 2530 2531 var node = ListOfInts.Node { 2532 .prev = null, 2533 .next = null, 2534 .data = 1234, 2535 }; 2536 var list2 = LinkedList(i32) { 2537 .first = &node, 2538 .last = &node, 2539 .len = 1, 2540 }; 2541 try expect(list2.first.?.data == 1234); 2542 } 2543 {#code_end#} 2544 2545 {#header_open|Default Field Values#} 2546 <p> 2547 Each struct field may have an expression indicating the default field value. Such expressions 2548 are executed at {#link|comptime#}, and allow the field to be omitted in a struct literal expression: 2549 </p> 2550 {#code_begin|test#} 2551 const Foo = struct { 2552 a: i32 = 1234, 2553 b: i32, 2554 }; 2555 2556 test "default struct initialization fields" { 2557 const x = Foo{ 2558 .b = 5, 2559 }; 2560 if (x.a + x.b != 1239) { 2561 @compileError("it's even comptime known!"); 2562 } 2563 } 2564 {#code_end#} 2565 {#header_close#} 2566 2567 {#header_open|extern struct#} 2568 <p>An {#syntax#}extern struct{#endsyntax#} has in-memory layout guaranteed to match the 2569 C ABI for the target.</p> 2570 <p>This kind of struct should only be used for compatibility with the C ABI. Every other 2571 use case should be solved with {#link|packed struct#} or normal {#link|struct#}.</p> 2572 {#see_also|extern union|extern enum#} 2573 {#header_close#} 2574 2575 {#header_open|packed struct#} 2576 <p> 2577 Unlike normal structs, {#syntax#}packed{#endsyntax#} structs have guaranteed in-memory layout: 2578 </p> 2579 <ul> 2580 <li>Fields remain in the order declared.</li> 2581 <li>There is no padding between fields.</li> 2582 <li>Zig supports arbitrary width {#link|Integers#} and although normally, integers with fewer 2583 than 8 bits will still use 1 byte of memory, in packed structs, they use 2584 exactly their bit width. 2585 </li> 2586 <li>{#syntax#}bool{#endsyntax#} fields use exactly 1 bit.</li> 2587 <li>An {#link|enum#} field uses exactly the bit width of its integer tag type.</li> 2588 <li>A {#link|packed union#} field uses exactly the bit width of the union field with 2589 the largest bit width.</li> 2590 <li>Non-ABI-aligned fields are packed into the smallest possible 2591 ABI-aligned integers in accordance with the target endianness. 2592 </li> 2593 </ul> 2594 <p> 2595 This means that a {#syntax#}packed struct{#endsyntax#} can participate 2596 in a {#link|@bitCast#} or a {#link|@ptrCast#} to reinterpret memory. 2597 This even works at {#link|comptime#}: 2598 </p> 2599 {#code_begin|test#} 2600 const std = @import("std"); 2601 const native_endian = @import("builtin").target.cpu.arch.endian(); 2602 const expect = std.testing.expect; 2603 2604 const Full = packed struct { 2605 number: u16, 2606 }; 2607 const Divided = packed struct { 2608 half1: u8, 2609 quarter3: u4, 2610 quarter4: u4, 2611 }; 2612 2613 test "@bitCast between packed structs" { 2614 try doTheTest(); 2615 comptime try doTheTest(); 2616 } 2617 2618 fn doTheTest() !void { 2619 try expect(@sizeOf(Full) == 2); 2620 try expect(@sizeOf(Divided) == 2); 2621 var full = Full{ .number = 0x1234 }; 2622 var divided = @bitCast(Divided, full); 2623 switch (native_endian) { 2624 .Big => { 2625 try expect(divided.half1 == 0x12); 2626 try expect(divided.quarter3 == 0x3); 2627 try expect(divided.quarter4 == 0x4); 2628 }, 2629 .Little => { 2630 try expect(divided.half1 == 0x34); 2631 try expect(divided.quarter3 == 0x2); 2632 try expect(divided.quarter4 == 0x1); 2633 }, 2634 } 2635 } 2636 {#code_end#} 2637 <p> 2638 Zig allows the address to be taken of a non-byte-aligned field: 2639 </p> 2640 {#code_begin|test#} 2641 const std = @import("std"); 2642 const expect = std.testing.expect; 2643 2644 const BitField = packed struct { 2645 a: u3, 2646 b: u3, 2647 c: u2, 2648 }; 2649 2650 var foo = BitField{ 2651 .a = 1, 2652 .b = 2, 2653 .c = 3, 2654 }; 2655 2656 test "pointer to non-byte-aligned field" { 2657 const ptr = &foo.b; 2658 try expect(ptr.* == 2); 2659 } 2660 {#code_end#} 2661 <p> 2662 However, the pointer to a non-byte-aligned field has special properties and cannot 2663 be passed when a normal pointer is expected: 2664 </p> 2665 {#code_begin|test_err|expected type#} 2666 const std = @import("std"); 2667 const expect = std.testing.expect; 2668 2669 const BitField = packed struct { 2670 a: u3, 2671 b: u3, 2672 c: u2, 2673 }; 2674 2675 var bit_field = BitField{ 2676 .a = 1, 2677 .b = 2, 2678 .c = 3, 2679 }; 2680 2681 test "pointer to non-bit-aligned field" { 2682 try expect(bar(&bit_field.b) == 2); 2683 } 2684 2685 fn bar(x: *const u3) u3 { 2686 return x.*; 2687 } 2688 {#code_end#} 2689 <p> 2690 In this case, the function {#syntax#}bar{#endsyntax#} cannot be called becuse the pointer 2691 to the non-ABI-aligned field mentions the bit offset, but the function expects an ABI-aligned pointer. 2692 </p> 2693 <p> 2694 Pointers to non-ABI-aligned fields share the same address as the other fields within their host integer: 2695 </p> 2696 {#code_begin|test#} 2697 const std = @import("std"); 2698 const expect = std.testing.expect; 2699 2700 const BitField = packed struct { 2701 a: u3, 2702 b: u3, 2703 c: u2, 2704 }; 2705 2706 var bit_field = BitField{ 2707 .a = 1, 2708 .b = 2, 2709 .c = 3, 2710 }; 2711 2712 test "pointer to non-bit-aligned field" { 2713 try expect(@ptrToInt(&bit_field.a) == @ptrToInt(&bit_field.b)); 2714 try expect(@ptrToInt(&bit_field.a) == @ptrToInt(&bit_field.c)); 2715 } 2716 {#code_end#} 2717 <p> 2718 This can be observed with {#link|@bitOffsetOf#} and {#link|offsetOf#}: 2719 </p> 2720 {#code_begin|test#} 2721 const std = @import("std"); 2722 const expect = std.testing.expect; 2723 2724 const BitField = packed struct { 2725 a: u3, 2726 b: u3, 2727 c: u2, 2728 }; 2729 2730 test "pointer to non-bit-aligned field" { 2731 comptime { 2732 try expect(@bitOffsetOf(BitField, "a") == 0); 2733 try expect(@bitOffsetOf(BitField, "b") == 3); 2734 try expect(@bitOffsetOf(BitField, "c") == 6); 2735 2736 try expect(@offsetOf(BitField, "a") == 0); 2737 try expect(@offsetOf(BitField, "b") == 0); 2738 try expect(@offsetOf(BitField, "c") == 0); 2739 } 2740 } 2741 {#code_end#} 2742 <p> 2743 Packed structs have 1-byte alignment. However if you have an overaligned pointer to a packed struct, 2744 Zig should correctly understand the alignment of fields. However there is 2745 <a href="https://github.com/ziglang/zig/issues/1994">a bug</a>: 2746 </p> 2747 {#code_begin|test_err#} 2748 const S = packed struct { 2749 a: u32, 2750 b: u32, 2751 }; 2752 test "overaligned pointer to packed struct" { 2753 var foo: S align(4) = undefined; 2754 const ptr: *align(4) S = &foo; 2755 const ptr_to_b: *u32 = &ptr.b; 2756 } 2757 {#code_end#} 2758 <p>When this bug is fixed, the above test in the documentation will unexpectedly pass, which will 2759 cause the test suite to fail, notifying the bug fixer to update these docs. 2760 </p> 2761 <p> 2762 It's also possible to set alignment of struct fields: 2763 </p> 2764 {#code_begin|test#} 2765 const std = @import("std"); 2766 const expectEqual = std.testing.expectEqual; 2767 2768 test "aligned struct fields" { 2769 const S = struct { 2770 a: u32 align(2), 2771 b: u32 align(64), 2772 }; 2773 var foo = S{ .a = 1, .b = 2 }; 2774 2775 try expectEqual(64, @alignOf(S)); 2776 try expectEqual(*align(2) u32, @TypeOf(&foo.a)); 2777 try expectEqual(*align(64) u32, @TypeOf(&foo.b)); 2778 } 2779 {#code_end#} 2780 <p> 2781 Using packed structs with {#link|volatile#} is problematic, and may be a compile error in the future. 2782 For details on this subscribe to 2783 <a href="https://github.com/ziglang/zig/issues/1761">this issue</a>. 2784 TODO update these docs with a recommendation on how to use packed structs with MMIO 2785 (the use case for volatile packed structs) once this issue is resolved. 2786 Don't worry, there will be a good solution for this use case in zig. 2787 </p> 2788 {#header_close#} 2789 2790 {#header_open|Struct Naming#} 2791 <p>Since all structs are anonymous, Zig infers the type name based on a few rules.</p> 2792 <ul> 2793 <li>If the struct is in the initialization expression of a variable, it gets named after 2794 that variable.</li> 2795 <li>If the struct is in the {#syntax#}return{#endsyntax#} expression, it gets named after 2796 the function it is returning from, with the parameter values serialized.</li> 2797 <li>Otherwise, the struct gets a name such as <code>(anonymous struct at file.zig:7:38)</code>.</li> 2798 </ul> 2799 {#code_begin|exe|struct_name#} 2800 const std = @import("std"); 2801 2802 pub fn main() void { 2803 const Foo = struct {}; 2804 std.debug.print("variable: {s}\n", .{@typeName(Foo)}); 2805 std.debug.print("anonymous: {s}\n", .{@typeName(struct {})}); 2806 std.debug.print("function: {s}\n", .{@typeName(List(i32))}); 2807 } 2808 2809 fn List(comptime T: type) type { 2810 return struct { 2811 x: T, 2812 }; 2813 } 2814 {#code_end#} 2815 {#header_close#} 2816 2817 {#header_open|Anonymous Struct Literals#} 2818 <p> 2819 Zig allows omitting the struct type of a literal. When the result is {#link|coerced|Type Coercion#}, 2820 the struct literal will directly instantiate the result location, with no copy: 2821 </p> 2822 {#code_begin|test|struct_result#} 2823 const std = @import("std"); 2824 const expect = std.testing.expect; 2825 2826 const Point = struct {x: i32, y: i32}; 2827 2828 test "anonymous struct literal" { 2829 var pt: Point = .{ 2830 .x = 13, 2831 .y = 67, 2832 }; 2833 try expect(pt.x == 13); 2834 try expect(pt.y == 67); 2835 } 2836 {#code_end#} 2837 <p> 2838 The struct type can be inferred. Here the result location does not include a type, and 2839 so Zig infers the type: 2840 </p> 2841 {#code_begin|test|struct_anon#} 2842 const std = @import("std"); 2843 const expect = std.testing.expect; 2844 2845 test "fully anonymous struct" { 2846 try dump(.{ 2847 .int = @as(u32, 1234), 2848 .float = @as(f64, 12.34), 2849 .b = true, 2850 .s = "hi", 2851 }); 2852 } 2853 2854 fn dump(args: anytype) !void { 2855 try expect(args.int == 1234); 2856 try expect(args.float == 12.34); 2857 try expect(args.b); 2858 try expect(args.s[0] == 'h'); 2859 try expect(args.s[1] == 'i'); 2860 } 2861 {#code_end#} 2862 <p> 2863 Anonymous structs can be created without specifying field names, and are referred to as "tuples". 2864 </p> 2865 <p> 2866 The fields are implicitly named using numbers starting from 0. Because their names are integers, 2867 the {#syntax#}@"0"{#endsyntax#} syntax must be used to access them. Names inside {#syntax#}@""{#endsyntax#} are always recognised as identifiers. 2868 </p> 2869 <p> 2870 Like arrays, tuples have a .len field, can be indexed and work with the ++ and ** operators. They can also be iterated over with {#link|inline for#}. 2871 </p> 2872 {#code_begin|test|tuple#} 2873 const std = @import("std"); 2874 const expect = std.testing.expect; 2875 2876 test "tuple" { 2877 const values = .{ 2878 @as(u32, 1234), 2879 @as(f64, 12.34), 2880 true, 2881 "hi", 2882 } ++ .{false} ** 2; 2883 try expect(values[0] == 1234); 2884 try expect(values[4] == false); 2885 inline for (values) |v, i| { 2886 if (i != 2) continue; 2887 try expect(v); 2888 } 2889 try expect(values.len == 6); 2890 try expect(values.@"3"[0] == 'h'); 2891 } 2892 {#code_end#} 2893 {#header_close#} 2894 {#see_also|comptime|@fieldParentPtr#} 2895 {#header_close#} 2896 {#header_open|enum#} 2897 {#code_begin|test|enums#} 2898 const expect = @import("std").testing.expect; 2899 const mem = @import("std").mem; 2900 2901 // Declare an enum. 2902 const Type = enum { 2903 ok, 2904 not_ok, 2905 }; 2906 2907 // Declare a specific instance of the enum variant. 2908 const c = Type.ok; 2909 2910 // If you want access to the ordinal value of an enum, you 2911 // can specify the tag type. 2912 const Value = enum(u2) { 2913 zero, 2914 one, 2915 two, 2916 }; 2917 2918 // Now you can cast between u2 and Value. 2919 // The ordinal value starts from 0, counting up for each member. 2920 test "enum ordinal value" { 2921 try expect(@enumToInt(Value.zero) == 0); 2922 try expect(@enumToInt(Value.one) == 1); 2923 try expect(@enumToInt(Value.two) == 2); 2924 } 2925 2926 // You can override the ordinal value for an enum. 2927 const Value2 = enum(u32) { 2928 hundred = 100, 2929 thousand = 1000, 2930 million = 1000000, 2931 }; 2932 test "set enum ordinal value" { 2933 try expect(@enumToInt(Value2.hundred) == 100); 2934 try expect(@enumToInt(Value2.thousand) == 1000); 2935 try expect(@enumToInt(Value2.million) == 1000000); 2936 } 2937 2938 // Enums can have methods, the same as structs and unions. 2939 // Enum methods are not special, they are only namespaced 2940 // functions that you can call with dot syntax. 2941 const Suit = enum { 2942 clubs, 2943 spades, 2944 diamonds, 2945 hearts, 2946 2947 pub fn isClubs(self: Suit) bool { 2948 return self == Suit.clubs; 2949 } 2950 }; 2951 test "enum method" { 2952 const p = Suit.spades; 2953 try expect(!p.isClubs()); 2954 } 2955 2956 // An enum variant of different types can be switched upon. 2957 const Foo = enum { 2958 string, 2959 number, 2960 none, 2961 }; 2962 test "enum variant switch" { 2963 const p = Foo.number; 2964 const what_is_it = switch (p) { 2965 Foo.string => "this is a string", 2966 Foo.number => "this is a number", 2967 Foo.none => "this is a none", 2968 }; 2969 try expect(mem.eql(u8, what_is_it, "this is a number")); 2970 } 2971 2972 // @typeInfo can be used to access the integer tag type of an enum. 2973 const Small = enum { 2974 one, 2975 two, 2976 three, 2977 four, 2978 }; 2979 test "std.meta.Tag" { 2980 try expect(@typeInfo(Small).Enum.tag_type == u2); 2981 } 2982 2983 // @typeInfo tells us the field count and the fields names: 2984 test "@typeInfo" { 2985 try expect(@typeInfo(Small).Enum.fields.len == 4); 2986 try expect(mem.eql(u8, @typeInfo(Small).Enum.fields[1].name, "two")); 2987 } 2988 2989 // @tagName gives a [:0]const u8 representation of an enum value: 2990 test "@tagName" { 2991 try expect(mem.eql(u8, @tagName(Small.three), "three")); 2992 } 2993 {#code_end#} 2994 {#see_also|@typeInfo|@tagName|@sizeOf#} 2995 2996 {#header_open|extern enum#} 2997 <p> 2998 By default, enums are not guaranteed to be compatible with the C ABI: 2999 </p> 3000 {#code_begin|obj_err|parameter of type 'Foo' not allowed in function with calling convention 'C'#} 3001 const Foo = enum { a, b, c }; 3002 export fn entry(foo: Foo) void { } 3003 {#code_end#} 3004 <p> 3005 For a C-ABI-compatible enum, use {#syntax#}extern enum{#endsyntax#}: 3006 </p> 3007 {#code_begin|obj#} 3008 const Foo = extern enum { a, b, c }; 3009 export fn entry(foo: Foo) void { } 3010 {#code_end#} 3011 {#header_close#} 3012 3013 {#header_open|Enum Literals#} 3014 <p> 3015 Enum literals allow specifying the name of an enum field without specifying the enum type: 3016 </p> 3017 {#code_begin|test#} 3018 const std = @import("std"); 3019 const expect = std.testing.expect; 3020 3021 const Color = enum { 3022 auto, 3023 off, 3024 on, 3025 }; 3026 3027 test "enum literals" { 3028 const color1: Color = .auto; 3029 const color2 = Color.auto; 3030 try expect(color1 == color2); 3031 } 3032 3033 test "switch using enum literals" { 3034 const color = Color.on; 3035 const result = switch (color) { 3036 .auto => false, 3037 .on => true, 3038 .off => false, 3039 }; 3040 try expect(result); 3041 } 3042 {#code_end#} 3043 {#header_close#} 3044 3045 {#header_open|Non-exhaustive enum#} 3046 <p> 3047 A Non-exhaustive enum can be created by adding a trailing '_' field. 3048 It must specify a tag type and cannot consume every enumeration value. 3049 </p> 3050 <p> 3051 {#link|@intToEnum#} on a non-exhaustive enum cannot fail. 3052 </p> 3053 <p> 3054 A switch on a non-exhaustive enum can include a '_' prong as an alternative to an {#syntax#}else{#endsyntax#} prong 3055 with the difference being that it makes it a compile error if all the known tag names are not handled by the switch. 3056 </p> 3057 {#code_begin|test#} 3058 const std = @import("std"); 3059 const expect = std.testing.expect; 3060 3061 const Number = enum(u8) { 3062 one, 3063 two, 3064 three, 3065 _, 3066 }; 3067 3068 test "switch on non-exhaustive enum" { 3069 const number = Number.one; 3070 const result = switch (number) { 3071 .one => true, 3072 .two, 3073 .three => false, 3074 _ => false, 3075 }; 3076 try expect(result); 3077 const is_one = switch (number) { 3078 .one => true, 3079 else => false, 3080 }; 3081 try expect(is_one); 3082 } 3083 {#code_end#} 3084 {#header_close#} 3085 {#header_close#} 3086 3087 {#header_open|union#} 3088 <p> 3089 A bare {#syntax#}union{#endsyntax#} defines a set of possible types that a value 3090 can be as a list of fields. Only one field can be active at a time. 3091 The in-memory representation of bare unions is not guaranteed. 3092 Bare unions cannot be used to reinterpret memory. For that, use {#link|@ptrCast#}, 3093 or use an {#link|extern union#} or a {#link|packed union#} which have 3094 guaranteed in-memory layout. 3095 {#link|Accessing the non-active field|Wrong Union Field Access#} is 3096 safety-checked {#link|Undefined Behavior#}: 3097 </p> 3098 {#code_begin|test_err|inactive union field#} 3099 const Payload = union { 3100 int: i64, 3101 float: f64, 3102 boolean: bool, 3103 }; 3104 test "simple union" { 3105 var payload = Payload{ .int = 1234 }; 3106 payload.float = 12.34; 3107 } 3108 {#code_end#} 3109 <p>You can activate another field by assigning the entire union:</p> 3110 {#code_begin|test#} 3111 const std = @import("std"); 3112 const expect = std.testing.expect; 3113 3114 const Payload = union { 3115 int: i64, 3116 float: f64, 3117 boolean: bool, 3118 }; 3119 test "simple union" { 3120 var payload = Payload{ .int = 1234 }; 3121 try expect(payload.int == 1234); 3122 payload = Payload{ .float = 12.34 }; 3123 try expect(payload.float == 12.34); 3124 } 3125 {#code_end#} 3126 <p> 3127 In order to use {#link|switch#} with a union, it must be a {#link|Tagged union#}. 3128 </p> 3129 <p> 3130 To initialize a union when the tag is a {#link|comptime#}-known name, see {#link|@unionInit#}. 3131 </p> 3132 3133 {#header_open|Tagged union#} 3134 <p>Unions can be declared with an enum tag type. 3135 This turns the union into a <em>tagged</em> union, which makes it eligible 3136 to use with {#link|switch#} expressions. 3137 Tagged unions coerce to their tag type: {#link|Type Coercion: unions and enums#}. 3138 </p> 3139 {#code_begin|test#} 3140 const std = @import("std"); 3141 const expect = std.testing.expect; 3142 3143 const ComplexTypeTag = enum { 3144 ok, 3145 not_ok, 3146 }; 3147 const ComplexType = union(ComplexTypeTag) { 3148 ok: u8, 3149 not_ok: void, 3150 }; 3151 3152 test "switch on tagged union" { 3153 const c = ComplexType{ .ok = 42 }; 3154 try expect(@as(ComplexTypeTag, c) == ComplexTypeTag.ok); 3155 3156 switch (c) { 3157 ComplexTypeTag.ok => |value| try expect(value == 42), 3158 ComplexTypeTag.not_ok => unreachable, 3159 } 3160 } 3161 3162 test "get tag type" { 3163 try expect(std.meta.Tag(ComplexType) == ComplexTypeTag); 3164 } 3165 3166 test "coerce to enum" { 3167 const c1 = ComplexType{ .ok = 42 }; 3168 const c2 = ComplexType.not_ok; 3169 3170 try expect(c1 == .ok); 3171 try expect(c2 == .not_ok); 3172 } 3173 {#code_end#} 3174 <p>In order to modify the payload of a tagged union in a switch expression, 3175 place a {#syntax#}*{#endsyntax#} before the variable name to make it a pointer: 3176 </p> 3177 {#code_begin|test#} 3178 const std = @import("std"); 3179 const expect = std.testing.expect; 3180 3181 const ComplexTypeTag = enum { 3182 ok, 3183 not_ok, 3184 }; 3185 const ComplexType = union(ComplexTypeTag) { 3186 ok: u8, 3187 not_ok: void, 3188 }; 3189 3190 test "modify tagged union in switch" { 3191 var c = ComplexType{ .ok = 42 }; 3192 try expect(@as(ComplexTypeTag, c) == ComplexTypeTag.ok); 3193 3194 switch (c) { 3195 ComplexTypeTag.ok => |*value| value.* += 1, 3196 ComplexTypeTag.not_ok => unreachable, 3197 } 3198 3199 try expect(c.ok == 43); 3200 } 3201 {#code_end#} 3202 <p> 3203 Unions can be made to infer the enum tag type. 3204 Further, unions can have methods just like structs and enums. 3205 </p> 3206 {#code_begin|test#} 3207 const std = @import("std"); 3208 const expect = std.testing.expect; 3209 3210 const Variant = union(enum) { 3211 int: i32, 3212 boolean: bool, 3213 3214 // void can be omitted when inferring enum tag type. 3215 none, 3216 3217 fn truthy(self: Variant) bool { 3218 return switch (self) { 3219 Variant.int => |x_int| x_int != 0, 3220 Variant.boolean => |x_bool| x_bool, 3221 Variant.none => false, 3222 }; 3223 } 3224 }; 3225 3226 test "union method" { 3227 var v1 = Variant{ .int = 1 }; 3228 var v2 = Variant{ .boolean = false }; 3229 3230 try expect(v1.truthy()); 3231 try expect(!v2.truthy()); 3232 } 3233 {#code_end#} 3234 <p> 3235 {#link|@tagName#} can be used to return a {#link|comptime#} 3236 {#syntax#}[:0]const u8{#endsyntax#} value representing the field name: 3237 </p> 3238 {#code_begin|test#} 3239 const std = @import("std"); 3240 const expect = std.testing.expect; 3241 3242 const Small2 = union(enum) { 3243 a: i32, 3244 b: bool, 3245 c: u8, 3246 }; 3247 test "@tagName" { 3248 try expect(std.mem.eql(u8, @tagName(Small2.a), "a")); 3249 } 3250 {#code_end#} 3251 {#header_close#} 3252 3253 {#header_open|extern union#} 3254 <p> 3255 An {#syntax#}extern union{#endsyntax#} has memory layout guaranteed to be compatible with 3256 the target C ABI. 3257 </p> 3258 {#see_also|extern struct#} 3259 {#header_close#} 3260 3261 {#header_open|packed union#} 3262 <p>A {#syntax#}packed union{#endsyntax#} has well-defined in-memory layout and is eligible 3263 to be in a {#link|packed struct#}. 3264 {#header_close#} 3265 3266 {#header_open|Anonymous Union Literals#} 3267 <p>{#link|Anonymous Struct Literals#} syntax can be used to initialize unions without specifying 3268 the type:</p> 3269 {#code_begin|test|anon_union#} 3270 const std = @import("std"); 3271 const expect = std.testing.expect; 3272 3273 const Number = union { 3274 int: i32, 3275 float: f64, 3276 }; 3277 3278 test "anonymous union literal syntax" { 3279 var i: Number = .{.int = 42}; 3280 var f = makeNumber(); 3281 try expect(i.int == 42); 3282 try expect(f.float == 12.34); 3283 } 3284 3285 fn makeNumber() Number { 3286 return .{.float = 12.34}; 3287 } 3288 {#code_end#} 3289 {#header_close#} 3290 3291 {#header_close#} 3292 3293 {#header_open|opaque#} 3294 <p> 3295 {#syntax#}opaque {}{#endsyntax#} declares a new type with an unknown (but non-zero) size and alignment. 3296 It can contain declarations the same as {#link|structs|struct#}, {#link|unions|union#}, 3297 and {#link|enums|enum#}. 3298 </p> 3299 <p> 3300 This is typically used for type safety when interacting with C code that does not expose struct details. 3301 Example: 3302 </p> 3303 {#code_begin|test_err|expected type '*Derp', found '*Wat'#} 3304 const Derp = opaque {}; 3305 const Wat = opaque {}; 3306 3307 extern fn bar(d: *Derp) void; 3308 fn foo(w: *Wat) callconv(.C) void { 3309 bar(w); 3310 } 3311 3312 test "call foo" { 3313 foo(undefined); 3314 } 3315 {#code_end#} 3316 {#header_close#} 3317 3318 {#header_open|blocks#} 3319 <p> 3320 Blocks are used to limit the scope of variable declarations: 3321 </p> 3322 {#code_begin|test_err|undeclared identifier#} 3323 test "access variable after block scope" { 3324 { 3325 var x: i32 = 1; 3326 } 3327 x += 1; 3328 } 3329 {#code_end#} 3330 <p>Blocks are expressions. When labeled, {#syntax#}break{#endsyntax#} can be used 3331 to return a value from the block: 3332 </p> 3333 {#code_begin|test#} 3334 const std = @import("std"); 3335 const expect = std.testing.expect; 3336 3337 test "labeled break from labeled block expression" { 3338 var y: i32 = 123; 3339 3340 const x = blk: { 3341 y += 1; 3342 break :blk y; 3343 }; 3344 try expect(x == 124); 3345 try expect(y == 124); 3346 } 3347 {#code_end#} 3348 <p>Here, {#syntax#}blk{#endsyntax#} can be any name.</p> 3349 {#see_also|Labeled while|Labeled for#} 3350 3351 {#header_open|Shadowing#} 3352 <p>It is never allowed for an identifier to "hide" another one by using the same name:</p> 3353 {#code_begin|test_err|redefinition#} 3354 const pi = 3.14; 3355 3356 test "inside test block" { 3357 // Let's even go inside another block 3358 { 3359 var pi: i32 = 1234; 3360 } 3361 } 3362 {#code_end#} 3363 <p> 3364 Because of this, when you read Zig code you can rely on an identifier always meaning the same thing, 3365 within the scope it is defined. Note that you can, however use the same name if the scopes are separate: 3366 </p> 3367 {#code_begin|test#} 3368 test "separate scopes" { 3369 { 3370 const pi = 3.14; 3371 } 3372 { 3373 var pi: bool = true; 3374 } 3375 } 3376 {#code_end#} 3377 {#header_close#} 3378 {#header_close#} 3379 3380 {#header_open|switch#} 3381 {#code_begin|test|switch#} 3382 const std = @import("std"); 3383 const expect = std.testing.expect; 3384 3385 test "switch simple" { 3386 const a: u64 = 10; 3387 const zz: u64 = 103; 3388 3389 // All branches of a switch expression must be able to be coerced to a 3390 // common type. 3391 // 3392 // Branches cannot fallthrough. If fallthrough behavior is desired, combine 3393 // the cases and use an if. 3394 const b = switch (a) { 3395 // Multiple cases can be combined via a ',' 3396 1, 2, 3 => 0, 3397 3398 // Ranges can be specified using the ... syntax. These are inclusive 3399 // both ends. 3400 5...100 => 1, 3401 3402 // Branches can be arbitrarily complex. 3403 101 => blk: { 3404 const c: u64 = 5; 3405 break :blk c * 2 + 1; 3406 }, 3407 3408 // Switching on arbitrary expressions is allowed as long as the 3409 // expression is known at compile-time. 3410 zz => zz, 3411 comptime blk: { 3412 const d: u32 = 5; 3413 const e: u32 = 100; 3414 break :blk d + e; 3415 } => 107, 3416 3417 // The else branch catches everything not already captured. 3418 // Else branches are mandatory unless the entire range of values 3419 // is handled. 3420 else => 9, 3421 }; 3422 3423 try expect(b == 1); 3424 } 3425 3426 // Switch expressions can be used outside a function: 3427 const os_msg = switch (std.Target.current.os.tag) { 3428 .linux => "we found a linux user", 3429 else => "not a linux user", 3430 }; 3431 3432 // Inside a function, switch statements implicitly are compile-time 3433 // evaluated if the target expression is compile-time known. 3434 test "switch inside function" { 3435 switch (std.Target.current.os.tag) { 3436 .fuchsia => { 3437 // On an OS other than fuchsia, block is not even analyzed, 3438 // so this compile error is not triggered. 3439 // On fuchsia this compile error would be triggered. 3440 @compileError("fuchsia not supported"); 3441 }, 3442 else => {}, 3443 } 3444 } 3445 {#code_end#} 3446 <p> 3447 {#syntax#}switch{#endsyntax#} can be used to capture the field values 3448 of a {#link|Tagged union#}. Modifications to the field values can be 3449 done by placing a {#syntax#}*{#endsyntax#} before the capture variable name, 3450 turning it into a pointer. 3451 </p> 3452 {#code_begin|test#} 3453 const expect = @import("std").testing.expect; 3454 3455 test "switch on tagged union" { 3456 const Point = struct { 3457 x: u8, 3458 y: u8, 3459 }; 3460 const Item = union(enum) { 3461 a: u32, 3462 c: Point, 3463 d, 3464 e: u32, 3465 }; 3466 3467 var a = Item{ .c = Point{ .x = 1, .y = 2 } }; 3468 3469 // Switching on more complex enums is allowed. 3470 const b = switch (a) { 3471 // A capture group is allowed on a match, and will return the enum 3472 // value matched. If the payload types of both cases are the same 3473 // they can be put into the same switch prong. 3474 Item.a, Item.e => |item| item, 3475 3476 // A reference to the matched value can be obtained using `*` syntax. 3477 Item.c => |*item| blk: { 3478 item.*.x += 1; 3479 break :blk 6; 3480 }, 3481 3482 // No else is required if the types cases was exhaustively handled 3483 Item.d => 8, 3484 }; 3485 3486 try expect(b == 6); 3487 try expect(a.c.x == 2); 3488 } 3489 {#code_end#} 3490 {#see_also|comptime|enum|@compileError|Compile Variables#} 3491 3492 {#header_open|Exhaustive Switching#} 3493 <p> 3494 When a {#syntax#}switch{#endsyntax#} expression does not have an {#syntax#}else{#endsyntax#} clause, 3495 it must exhaustively list all the possible values. Failure to do so is a compile error: 3496 </p> 3497 {#code_begin|test_err|not handled in switch#} 3498 const Color = enum { 3499 auto, 3500 off, 3501 on, 3502 }; 3503 3504 test "exhaustive switching" { 3505 const color = Color.off; 3506 switch (color) { 3507 Color.auto => {}, 3508 Color.on => {}, 3509 } 3510 } 3511 {#code_end#} 3512 {#header_close#} 3513 3514 {#header_open|Switching with Enum Literals#} 3515 <p> 3516 {#link|Enum Literals#} can be useful to use with {#syntax#}switch{#endsyntax#} to avoid 3517 repetitively specifying {#link|enum#} or {#link|union#} types: 3518 </p> 3519 {#code_begin|test#} 3520 const std = @import("std"); 3521 const expect = std.testing.expect; 3522 3523 const Color = enum { 3524 auto, 3525 off, 3526 on, 3527 }; 3528 3529 test "enum literals with switch" { 3530 const color = Color.off; 3531 const result = switch (color) { 3532 .auto => false, 3533 .on => false, 3534 .off => true, 3535 }; 3536 try expect(result); 3537 } 3538 {#code_end#} 3539 {#header_close#} 3540 {#header_close#} 3541 3542 {#header_open|while#} 3543 <p> 3544 A while loop is used to repeatedly execute an expression until 3545 some condition is no longer true. 3546 </p> 3547 {#code_begin|test|while#} 3548 const expect = @import("std").testing.expect; 3549 3550 test "while basic" { 3551 var i: usize = 0; 3552 while (i < 10) { 3553 i += 1; 3554 } 3555 try expect(i == 10); 3556 } 3557 {#code_end#} 3558 <p> 3559 Use {#syntax#}break{#endsyntax#} to exit a while loop early. 3560 </p> 3561 {#code_begin|test|while#} 3562 const expect = @import("std").testing.expect; 3563 3564 test "while break" { 3565 var i: usize = 0; 3566 while (true) { 3567 if (i == 10) 3568 break; 3569 i += 1; 3570 } 3571 try expect(i == 10); 3572 } 3573 {#code_end#} 3574 <p> 3575 Use {#syntax#}continue{#endsyntax#} to jump back to the beginning of the loop. 3576 </p> 3577 {#code_begin|test|while#} 3578 const expect = @import("std").testing.expect; 3579 3580 test "while continue" { 3581 var i: usize = 0; 3582 while (true) { 3583 i += 1; 3584 if (i < 10) 3585 continue; 3586 break; 3587 } 3588 try expect(i == 10); 3589 } 3590 {#code_end#} 3591 <p> 3592 While loops support a continue expression which is executed when the loop 3593 is continued. The {#syntax#}continue{#endsyntax#} keyword respects this expression. 3594 </p> 3595 {#code_begin|test|while#} 3596 const expect = @import("std").testing.expect; 3597 3598 test "while loop continue expression" { 3599 var i: usize = 0; 3600 while (i < 10) : (i += 1) {} 3601 try expect(i == 10); 3602 } 3603 3604 test "while loop continue expression, more complicated" { 3605 var i: usize = 1; 3606 var j: usize = 1; 3607 while (i * j < 2000) : ({ i *= 2; j *= 3; }) { 3608 const my_ij = i * j; 3609 try expect(my_ij < 2000); 3610 } 3611 } 3612 {#code_end#} 3613 <p> 3614 While loops are expressions. The result of the expression is the 3615 result of the {#syntax#}else{#endsyntax#} clause of a while loop, which is executed when 3616 the condition of the while loop is tested as false. 3617 </p> 3618 <p> 3619 {#syntax#}break{#endsyntax#}, like {#syntax#}return{#endsyntax#}, accepts a value 3620 parameter. This is the result of the {#syntax#}while{#endsyntax#} expression. 3621 When you {#syntax#}break{#endsyntax#} from a while loop, the {#syntax#}else{#endsyntax#} branch is not 3622 evaluated. 3623 </p> 3624 {#code_begin|test|while#} 3625 const expect = @import("std").testing.expect; 3626 3627 test "while else" { 3628 try expect(rangeHasNumber(0, 10, 5)); 3629 try expect(!rangeHasNumber(0, 10, 15)); 3630 } 3631 3632 fn rangeHasNumber(begin: usize, end: usize, number: usize) bool { 3633 var i = begin; 3634 return while (i < end) : (i += 1) { 3635 if (i == number) { 3636 break true; 3637 } 3638 } else false; 3639 } 3640 {#code_end#} 3641 {#header_open|Labeled while#} 3642 <p>When a {#syntax#}while{#endsyntax#} loop is labeled, it can be referenced from a {#syntax#}break{#endsyntax#} 3643 or {#syntax#}continue{#endsyntax#} from within a nested loop:</p> 3644 {#code_begin|test#} 3645 test "nested break" { 3646 outer: while (true) { 3647 while (true) { 3648 break :outer; 3649 } 3650 } 3651 } 3652 3653 test "nested continue" { 3654 var i: usize = 0; 3655 outer: while (i < 10) : (i += 1) { 3656 while (true) { 3657 continue :outer; 3658 } 3659 } 3660 } 3661 {#code_end#} 3662 {#header_close#} 3663 {#header_open|while with Optionals#} 3664 <p> 3665 Just like {#link|if#} expressions, while loops can take an optional as the 3666 condition and capture the payload. When {#link|null#} is encountered the loop 3667 exits. 3668 </p> 3669 <p> 3670 When the {#syntax#}|x|{#endsyntax#} syntax is present on a {#syntax#}while{#endsyntax#} expression, 3671 the while condition must have an {#link|Optional Type#}. 3672 </p> 3673 <p> 3674 The {#syntax#}else{#endsyntax#} branch is allowed on optional iteration. In this case, it will 3675 be executed on the first null value encountered. 3676 </p> 3677 {#code_begin|test|while#} 3678 const expect = @import("std").testing.expect; 3679 3680 test "while null capture" { 3681 var sum1: u32 = 0; 3682 numbers_left = 3; 3683 while (eventuallyNullSequence()) |value| { 3684 sum1 += value; 3685 } 3686 try expect(sum1 == 3); 3687 3688 var sum2: u32 = 0; 3689 numbers_left = 3; 3690 while (eventuallyNullSequence()) |value| { 3691 sum2 += value; 3692 } else { 3693 try expect(sum2 == 3); 3694 } 3695 } 3696 3697 var numbers_left: u32 = undefined; 3698 fn eventuallyNullSequence() ?u32 { 3699 return if (numbers_left == 0) null else blk: { 3700 numbers_left -= 1; 3701 break :blk numbers_left; 3702 }; 3703 } 3704 3705 {#code_end#} 3706 {#header_close#} 3707 3708 {#header_open|while with Error Unions#} 3709 <p> 3710 Just like {#link|if#} expressions, while loops can take an error union as 3711 the condition and capture the payload or the error code. When the 3712 condition results in an error code the else branch is evaluated and 3713 the loop is finished. 3714 </p> 3715 <p> 3716 When the {#syntax#}else |x|{#endsyntax#} syntax is present on a {#syntax#}while{#endsyntax#} expression, 3717 the while condition must have an {#link|Error Union Type#}. 3718 </p> 3719 {#code_begin|test|while#} 3720 const expect = @import("std").testing.expect; 3721 3722 test "while error union capture" { 3723 var sum1: u32 = 0; 3724 numbers_left = 3; 3725 while (eventuallyErrorSequence()) |value| { 3726 sum1 += value; 3727 } else |err| { 3728 try expect(err == error.ReachedZero); 3729 } 3730 } 3731 3732 var numbers_left: u32 = undefined; 3733 3734 fn eventuallyErrorSequence() anyerror!u32 { 3735 return if (numbers_left == 0) error.ReachedZero else blk: { 3736 numbers_left -= 1; 3737 break :blk numbers_left; 3738 }; 3739 } 3740 {#code_end#} 3741 {#header_close#} 3742 3743 {#header_open|inline while#} 3744 <p> 3745 While loops can be inlined. This causes the loop to be unrolled, which 3746 allows the code to do some things which only work at compile time, 3747 such as use types as first class values. 3748 </p> 3749 {#code_begin|test#} 3750 const expect = @import("std").testing.expect; 3751 3752 test "inline while loop" { 3753 comptime var i = 0; 3754 var sum: usize = 0; 3755 inline while (i < 3) : (i += 1) { 3756 const T = switch (i) { 3757 0 => f32, 3758 1 => i8, 3759 2 => bool, 3760 else => unreachable, 3761 }; 3762 sum += typeNameLength(T); 3763 } 3764 try expect(sum == 9); 3765 } 3766 3767 fn typeNameLength(comptime T: type) usize { 3768 return @typeName(T).len; 3769 } 3770 {#code_end#} 3771 <p> 3772 It is recommended to use {#syntax#}inline{#endsyntax#} loops only for one of these reasons: 3773 </p> 3774 <ul> 3775 <li>You need the loop to execute at {#link|comptime#} for the semantics to work.</li> 3776 <li> 3777 You have a benchmark to prove that forcibly unrolling the loop in this way is measurably faster. 3778 </li> 3779 </ul> 3780 {#header_close#} 3781 {#see_also|if|Optionals|Errors|comptime|unreachable#} 3782 {#header_close#} 3783 {#header_open|for#} 3784 {#code_begin|test|for#} 3785 const expect = @import("std").testing.expect; 3786 3787 test "for basics" { 3788 const items = [_]i32 { 4, 5, 3, 4, 0 }; 3789 var sum: i32 = 0; 3790 3791 // For loops iterate over slices and arrays. 3792 for (items) |value| { 3793 // Break and continue are supported. 3794 if (value == 0) { 3795 continue; 3796 } 3797 sum += value; 3798 } 3799 try expect(sum == 16); 3800 3801 // To iterate over a portion of a slice, reslice. 3802 for (items[0..1]) |value| { 3803 sum += value; 3804 } 3805 try expect(sum == 20); 3806 3807 // To access the index of iteration, specify a second capture value. 3808 // This is zero-indexed. 3809 var sum2: i32 = 0; 3810 for (items) |value, i| { 3811 try expect(@TypeOf(i) == usize); 3812 sum2 += @intCast(i32, i); 3813 } 3814 try expect(sum2 == 10); 3815 } 3816 3817 test "for reference" { 3818 var items = [_]i32 { 3, 4, 2 }; 3819 3820 // Iterate over the slice by reference by 3821 // specifying that the capture value is a pointer. 3822 for (items) |*value| { 3823 value.* += 1; 3824 } 3825 3826 try expect(items[0] == 4); 3827 try expect(items[1] == 5); 3828 try expect(items[2] == 3); 3829 } 3830 3831 test "for else" { 3832 // For allows an else attached to it, the same as a while loop. 3833 var items = [_]?i32 { 3, 4, null, 5 }; 3834 3835 // For loops can also be used as expressions. 3836 // Similar to while loops, when you break from a for loop, the else branch is not evaluated. 3837 var sum: i32 = 0; 3838 const result = for (items) |value| { 3839 if (value != null) { 3840 sum += value.?; 3841 } 3842 } else blk: { 3843 try expect(sum == 12); 3844 break :blk sum; 3845 }; 3846 try expect(result == 12); 3847 } 3848 {#code_end#} 3849 {#header_open|Labeled for#} 3850 <p>When a {#syntax#}for{#endsyntax#} loop is labeled, it can be referenced from a {#syntax#}break{#endsyntax#} 3851 or {#syntax#}continue{#endsyntax#} from within a nested loop:</p> 3852 {#code_begin|test#} 3853 const std = @import("std"); 3854 const expect = std.testing.expect; 3855 3856 test "nested break" { 3857 var count: usize = 0; 3858 outer: for ([_]i32{ 1, 2, 3, 4, 5 }) |_| { 3859 for ([_]i32{ 1, 2, 3, 4, 5 }) |_| { 3860 count += 1; 3861 break :outer; 3862 } 3863 } 3864 try expect(count == 1); 3865 } 3866 3867 test "nested continue" { 3868 var count: usize = 0; 3869 outer: for ([_]i32{ 1, 2, 3, 4, 5, 6, 7, 8 }) |_| { 3870 for ([_]i32{ 1, 2, 3, 4, 5 }) |_| { 3871 count += 1; 3872 continue :outer; 3873 } 3874 } 3875 3876 try expect(count == 8); 3877 } 3878 {#code_end#} 3879 {#header_close#} 3880 {#header_open|inline for#} 3881 <p> 3882 For loops can be inlined. This causes the loop to be unrolled, which 3883 allows the code to do some things which only work at compile time, 3884 such as use types as first class values. 3885 The capture value and iterator value of inlined for loops are 3886 compile-time known. 3887 </p> 3888 {#code_begin|test#} 3889 const expect = @import("std").testing.expect; 3890 3891 test "inline for loop" { 3892 const nums = [_]i32{2, 4, 6}; 3893 var sum: usize = 0; 3894 inline for (nums) |i| { 3895 const T = switch (i) { 3896 2 => f32, 3897 4 => i8, 3898 6 => bool, 3899 else => unreachable, 3900 }; 3901 sum += typeNameLength(T); 3902 } 3903 try expect(sum == 9); 3904 } 3905 3906 fn typeNameLength(comptime T: type) usize { 3907 return @typeName(T).len; 3908 } 3909 {#code_end#} 3910 <p> 3911 It is recommended to use {#syntax#}inline{#endsyntax#} loops only for one of these reasons: 3912 </p> 3913 <ul> 3914 <li>You need the loop to execute at {#link|comptime#} for the semantics to work.</li> 3915 <li> 3916 You have a benchmark to prove that forcibly unrolling the loop in this way is measurably faster. 3917 </li> 3918 </ul> 3919 {#header_close#} 3920 {#see_also|while|comptime|Arrays|Slices#} 3921 {#header_close#} 3922 {#header_open|if#} 3923 {#code_begin|test|if#} 3924 // If expressions have three uses, corresponding to the three types: 3925 // * bool 3926 // * ?T 3927 // * anyerror!T 3928 3929 const expect = @import("std").testing.expect; 3930 3931 test "if expression" { 3932 // If expressions are used instead of a ternary expression. 3933 const a: u32 = 5; 3934 const b: u32 = 4; 3935 const result = if (a != b) 47 else 3089; 3936 try expect(result == 47); 3937 } 3938 3939 test "if boolean" { 3940 // If expressions test boolean conditions. 3941 const a: u32 = 5; 3942 const b: u32 = 4; 3943 if (a != b) { 3944 try expect(true); 3945 } else if (a == 9) { 3946 unreachable; 3947 } else { 3948 unreachable; 3949 } 3950 } 3951 3952 test "if optional" { 3953 // If expressions test for null. 3954 3955 const a: ?u32 = 0; 3956 if (a) |value| { 3957 try expect(value == 0); 3958 } else { 3959 unreachable; 3960 } 3961 3962 const b: ?u32 = null; 3963 if (b) |value| { 3964 unreachable; 3965 } else { 3966 try expect(true); 3967 } 3968 3969 // The else is not required. 3970 if (a) |value| { 3971 try expect(value == 0); 3972 } 3973 3974 // To test against null only, use the binary equality operator. 3975 if (b == null) { 3976 try expect(true); 3977 } 3978 3979 // Access the value by reference using a pointer capture. 3980 var c: ?u32 = 3; 3981 if (c) |*value| { 3982 value.* = 2; 3983 } 3984 3985 if (c) |value| { 3986 try expect(value == 2); 3987 } else { 3988 unreachable; 3989 } 3990 } 3991 3992 test "if error union" { 3993 // If expressions test for errors. 3994 // Note the |err| capture on the else. 3995 3996 const a: anyerror!u32 = 0; 3997 if (a) |value| { 3998 try expect(value == 0); 3999 } else |err| { 4000 unreachable; 4001 } 4002 4003 const b: anyerror!u32 = error.BadValue; 4004 if (b) |value| { 4005 unreachable; 4006 } else |err| { 4007 try expect(err == error.BadValue); 4008 } 4009 4010 // The else and |err| capture is strictly required. 4011 if (a) |value| { 4012 try expect(value == 0); 4013 } else |_| {} 4014 4015 // To check only the error value, use an empty block expression. 4016 if (b) |_| {} else |err| { 4017 try expect(err == error.BadValue); 4018 } 4019 4020 // Access the value by reference using a pointer capture. 4021 var c: anyerror!u32 = 3; 4022 if (c) |*value| { 4023 value.* = 9; 4024 } else |err| { 4025 unreachable; 4026 } 4027 4028 if (c) |value| { 4029 try expect(value == 9); 4030 } else |err| { 4031 unreachable; 4032 } 4033 } 4034 4035 test "if error union with optional" { 4036 // If expressions test for errors before unwrapping optionals. 4037 // The |optional_value| capture's type is ?u32. 4038 4039 const a: anyerror!?u32 = 0; 4040 if (a) |optional_value| { 4041 try expect(optional_value.? == 0); 4042 } else |err| { 4043 unreachable; 4044 } 4045 4046 const b: anyerror!?u32 = null; 4047 if (b) |optional_value| { 4048 try expect(optional_value == null); 4049 } else |err| { 4050 unreachable; 4051 } 4052 4053 const c: anyerror!?u32 = error.BadValue; 4054 if (c) |optional_value| { 4055 unreachable; 4056 } else |err| { 4057 try expect(err == error.BadValue); 4058 } 4059 4060 // Access the value by reference by using a pointer capture each time. 4061 var d: anyerror!?u32 = 3; 4062 if (d) |*optional_value| { 4063 if (optional_value.*) |*value| { 4064 value.* = 9; 4065 } 4066 } else |err| { 4067 unreachable; 4068 } 4069 4070 if (d) |optional_value| { 4071 try expect(optional_value.? == 9); 4072 } else |err| { 4073 unreachable; 4074 } 4075 } 4076 {#code_end#} 4077 {#see_also|Optionals|Errors#} 4078 {#header_close#} 4079 {#header_open|defer#} 4080 {#code_begin|test|defer#} 4081 const std = @import("std"); 4082 const expect = std.testing.expect; 4083 const print = std.debug.print; 4084 4085 // defer will execute an expression at the end of the current scope. 4086 fn deferExample() !usize { 4087 var a: usize = 1; 4088 4089 { 4090 defer a = 2; 4091 a = 1; 4092 } 4093 try expect(a == 2); 4094 4095 a = 5; 4096 return a; 4097 } 4098 4099 test "defer basics" { 4100 try expect((try deferExample()) == 5); 4101 } 4102 4103 // If multiple defer statements are specified, they will be executed in 4104 // the reverse order they were run. 4105 fn deferUnwindExample() void { 4106 print("\n", .{}); 4107 4108 defer { 4109 print("1 ", .{}); 4110 } 4111 defer { 4112 print("2 ", .{}); 4113 } 4114 if (false) { 4115 // defers are not run if they are never executed. 4116 defer { 4117 print("3 ", .{}); 4118 } 4119 } 4120 } 4121 4122 test "defer unwinding" { 4123 deferUnwindExample(); 4124 } 4125 4126 // The errdefer keyword is similar to defer, but will only execute if the 4127 // scope returns with an error. 4128 // 4129 // This is especially useful in allowing a function to clean up properly 4130 // on error, and replaces goto error handling tactics as seen in c. 4131 fn deferErrorExample(is_error: bool) !void { 4132 print("\nstart of function\n", .{}); 4133 4134 // This will always be executed on exit 4135 defer { 4136 print("end of function\n", .{}); 4137 } 4138 4139 errdefer { 4140 print("encountered an error!\n", .{}); 4141 } 4142 4143 if (is_error) { 4144 return error.DeferError; 4145 } 4146 } 4147 4148 test "errdefer unwinding" { 4149 deferErrorExample(false) catch {}; 4150 deferErrorExample(true) catch {}; 4151 } 4152 {#code_end#} 4153 {#see_also|Errors#} 4154 {#header_close#} 4155 {#header_open|unreachable#} 4156 <p> 4157 In {#syntax#}Debug{#endsyntax#} and {#syntax#}ReleaseSafe{#endsyntax#} mode, and when using <code>zig test</code>, 4158 {#syntax#}unreachable{#endsyntax#} emits a call to {#syntax#}panic{#endsyntax#} with the message <code>reached unreachable code</code>. 4159 </p> 4160 <p> 4161 In {#syntax#}ReleaseFast{#endsyntax#} mode, the optimizer uses the assumption that {#syntax#}unreachable{#endsyntax#} code 4162 will never be hit to perform optimizations. However, <code>zig test</code> even in {#syntax#}ReleaseFast{#endsyntax#} mode 4163 still emits {#syntax#}unreachable{#endsyntax#} as calls to {#syntax#}panic{#endsyntax#}. 4164 </p> 4165 {#header_open|Basics#} 4166 {#code_begin|test#} 4167 // unreachable is used to assert that control flow will never happen upon a 4168 // particular location: 4169 test "basic math" { 4170 const x = 1; 4171 const y = 2; 4172 if (x + y != 3) { 4173 unreachable; 4174 } 4175 } 4176 {#code_end#} 4177 <p>In fact, this is how {#syntax#}std.debug.assert{#endsyntax#} is implemented:</p> 4178 {#code_begin|test_err#} 4179 // This is how std.debug.assert is implemented 4180 fn assert(ok: bool) void { 4181 if (!ok) unreachable; // assertion failure 4182 } 4183 4184 // This test will fail because we hit unreachable. 4185 test "this will fail" { 4186 assert(false); 4187 } 4188 {#code_end#} 4189 {#header_close#} 4190 {#header_open|At Compile-Time#} 4191 {#code_begin|test_err|unreachable code#} 4192 const assert = @import("std").debug.assert; 4193 4194 test "type of unreachable" { 4195 comptime { 4196 // The type of unreachable is noreturn. 4197 4198 // However this assertion will still fail because 4199 // evaluating unreachable at compile-time is a compile error. 4200 4201 assert(@TypeOf(unreachable) == noreturn); 4202 } 4203 } 4204 {#code_end#} 4205 {#see_also|Zig Test|Build Mode|comptime#} 4206 {#header_close#} 4207 {#header_close#} 4208 {#header_open|noreturn#} 4209 <p> 4210 {#syntax#}noreturn{#endsyntax#} is the type of: 4211 </p> 4212 <ul> 4213 <li>{#syntax#}break{#endsyntax#}</li> 4214 <li>{#syntax#}continue{#endsyntax#}</li> 4215 <li>{#syntax#}return{#endsyntax#}</li> 4216 <li>{#syntax#}unreachable{#endsyntax#}</li> 4217 <li>{#syntax#}while (true) {}{#endsyntax#}</li> 4218 </ul> 4219 <p>When resolving types together, such as {#syntax#}if{#endsyntax#} clauses or {#syntax#}switch{#endsyntax#} prongs, 4220 the {#syntax#}noreturn{#endsyntax#} type is compatible with every other type. Consider: 4221 </p> 4222 {#code_begin|test#} 4223 fn foo(condition: bool, b: u32) void { 4224 const a = if (condition) b else return; 4225 @panic("do something with a"); 4226 } 4227 test "noreturn" { 4228 foo(false, 1); 4229 } 4230 {#code_end#} 4231 <p>Another use case for {#syntax#}noreturn{#endsyntax#} is the {#syntax#}exit{#endsyntax#} function:</p> 4232 {#code_begin|test#} 4233 {#target_windows#} 4234 pub extern "kernel32" fn ExitProcess(exit_code: c_uint) callconv(if (@import("builtin").target.cpu.arch == .i386) .Stdcall else .C) noreturn; 4235 4236 test "foo" { 4237 const value = bar() catch ExitProcess(1); 4238 try expect(value == 1234); 4239 } 4240 4241 fn bar() anyerror!u32 { 4242 return 1234; 4243 } 4244 4245 const expect = @import("std").testing.expect; 4246 {#code_end#} 4247 {#header_close#} 4248 {#header_open|Functions#} 4249 {#code_begin|test|functions#} 4250 const expect = @import("std").testing.expect; 4251 4252 // Functions are declared like this 4253 fn add(a: i8, b: i8) i8 { 4254 if (a == 0) { 4255 return b; 4256 } 4257 4258 return a + b; 4259 } 4260 4261 // The export specifier makes a function externally visible in the generated 4262 // object file, and makes it use the C ABI. 4263 export fn sub(a: i8, b: i8) i8 { return a - b; } 4264 4265 // The extern specifier is used to declare a function that will be resolved 4266 // at link time, when linking statically, or at runtime, when linking 4267 // dynamically. 4268 // The callconv specifier changes the calling convention of the function. 4269 extern "kernel32" fn ExitProcess(exit_code: u32) callconv(if (@import("builtin").target.cpu.arch == .i386) .Stdcall else .C) noreturn; 4270 extern "c" fn atan2(a: f64, b: f64) f64; 4271 4272 // The @setCold builtin tells the optimizer that a function is rarely called. 4273 fn abort() noreturn { 4274 @setCold(true); 4275 while (true) {} 4276 } 4277 4278 // The naked calling convention makes a function not have any function prologue or epilogue. 4279 // This can be useful when integrating with assembly. 4280 fn _start() callconv(.Naked) noreturn { 4281 abort(); 4282 } 4283 4284 // The inline calling convention forces a function to be inlined at all call sites. 4285 // If the function cannot be inlined, it is a compile-time error. 4286 fn shiftLeftOne(a: u32) callconv(.Inline) u32 { 4287 return a << 1; 4288 } 4289 4290 // The pub specifier allows the function to be visible when importing. 4291 // Another file can use @import and call sub2 4292 pub fn sub2(a: i8, b: i8) i8 { return a - b; } 4293 4294 // Functions can be used as values and are equivalent to pointers. 4295 const call2_op = fn (a: i8, b: i8) i8; 4296 fn do_op(fn_call: call2_op, op1: i8, op2: i8) i8 { 4297 return fn_call(op1, op2); 4298 } 4299 4300 test "function" { 4301 try expect(do_op(add, 5, 6) == 11); 4302 try expect(do_op(sub2, 5, 6) == -1); 4303 } 4304 {#code_end#} 4305 <p>Function values are like pointers:</p> 4306 {#code_begin|obj#} 4307 const assert = @import("std").debug.assert; 4308 4309 comptime { 4310 assert(@TypeOf(foo) == fn()void); 4311 assert(@sizeOf(fn()void) == @sizeOf(?fn()void)); 4312 } 4313 4314 fn foo() void { } 4315 {#code_end#} 4316 {#header_open|Pass-by-value Parameters#} 4317 <p> 4318 Primitive types such as {#link|Integers#} and {#link|Floats#} passed as parameters 4319 are copied, and then the copy is available in the function body. This is called "passing by value". 4320 Copying a primitive type is essentially free and typically involves nothing more than 4321 setting a register. 4322 </p> 4323 <p> 4324 Structs, unions, and arrays can sometimes be more efficiently passed as a reference, since a copy 4325 could be arbitrarily expensive depending on the size. When these types are passed 4326 as parameters, Zig may choose to copy and pass by value, or pass by reference, whichever way 4327 Zig decides will be faster. This is made possible, in part, by the fact that parameters are immutable. 4328 </p> 4329 {#code_begin|test#} 4330 const Point = struct { 4331 x: i32, 4332 y: i32, 4333 }; 4334 4335 fn foo(point: Point) i32 { 4336 // Here, `point` could be a reference, or a copy. The function body 4337 // can ignore the difference and treat it as a value. Be very careful 4338 // taking the address of the parameter - it should be treated as if 4339 // the address will become invalid when the function returns. 4340 return point.x + point.y; 4341 } 4342 4343 const expect = @import("std").testing.expect; 4344 4345 test "pass struct to function" { 4346 try expect(foo(Point{ .x = 1, .y = 2 }) == 3); 4347 } 4348 {#code_end#} 4349 <p> 4350 For extern functions, Zig follows the C ABI for passing structs and unions by value. 4351 </p> 4352 {#header_close#} 4353 {#header_open|Function Parameter Type Inference#} 4354 <p> 4355 Function parameters can be declared with {#syntax#}anytype{#endsyntax#} in place of the type. 4356 In this case the parameter types will be inferred when the function is called. 4357 Use {#link|@TypeOf#} and {#link|@typeInfo#} to get information about the inferred type. 4358 </p> 4359 {#code_begin|test#} 4360 const expect = @import("std").testing.expect; 4361 4362 fn addFortyTwo(x: anytype) @TypeOf(x) { 4363 return x + 42; 4364 } 4365 4366 test "fn type inference" { 4367 try expect(addFortyTwo(1) == 43); 4368 try expect(@TypeOf(addFortyTwo(1)) == comptime_int); 4369 var y: i64 = 2; 4370 try expect(addFortyTwo(y) == 44); 4371 try expect(@TypeOf(addFortyTwo(y)) == i64); 4372 } 4373 {#code_end#} 4374 4375 {#header_close#} 4376 {#header_open|Function Reflection#} 4377 {#code_begin|test#} 4378 const expect = @import("std").testing.expect; 4379 4380 test "fn reflection" { 4381 try expect(@typeInfo(@TypeOf(expect)).Fn.args[0].arg_type.? == bool); 4382 try expect(@typeInfo(@TypeOf(expect)).Fn.is_var_args == false); 4383 } 4384 {#code_end#} 4385 {#header_close#} 4386 {#header_close#} 4387 {#header_open|Errors#} 4388 {#header_open|Error Set Type#} 4389 <p> 4390 An error set is like an {#link|enum#}. 4391 However, each error name across the entire compilation gets assigned an unsigned integer 4392 greater than 0. You are allowed to declare the same error name more than once, and if you do, it 4393 gets assigned the same integer value. 4394 </p> 4395 <p> 4396 The number of unique error values across the entire compilation should determine the size of the error set type. 4397 However right now it is hard coded to be a {#syntax#}u16{#endsyntax#}. See <a href="https://github.com/ziglang/zig/issues/786">#768</a>. 4398 </p> 4399 <p> 4400 You can {#link|coerce|Type Coercion#} an error from a subset to a superset: 4401 </p> 4402 {#code_begin|test#} 4403 const std = @import("std"); 4404 4405 const FileOpenError = error { 4406 AccessDenied, 4407 OutOfMemory, 4408 FileNotFound, 4409 }; 4410 4411 const AllocationError = error { 4412 OutOfMemory, 4413 }; 4414 4415 test "coerce subset to superset" { 4416 const err = foo(AllocationError.OutOfMemory); 4417 try std.testing.expect(err == FileOpenError.OutOfMemory); 4418 } 4419 4420 fn foo(err: AllocationError) FileOpenError { 4421 return err; 4422 } 4423 {#code_end#} 4424 <p> 4425 But you cannot {#link|coerce|Type Coercion#} an error from a superset to a subset: 4426 </p> 4427 {#code_begin|test_err|not a member of destination error set#} 4428 const FileOpenError = error { 4429 AccessDenied, 4430 OutOfMemory, 4431 FileNotFound, 4432 }; 4433 4434 const AllocationError = error { 4435 OutOfMemory, 4436 }; 4437 4438 test "coerce superset to subset" { 4439 foo(FileOpenError.OutOfMemory) catch {}; 4440 } 4441 4442 fn foo(err: FileOpenError) AllocationError { 4443 return err; 4444 } 4445 {#code_end#} 4446 <p> 4447 There is a shortcut for declaring an error set with only 1 value, and then getting that value: 4448 </p> 4449 {#code_begin|syntax#} 4450 const err = error.FileNotFound; 4451 {#code_end#} 4452 <p>This is equivalent to:</p> 4453 {#code_begin|syntax#} 4454 const err = (error {FileNotFound}).FileNotFound; 4455 {#code_end#} 4456 <p> 4457 This becomes useful when using {#link|Inferred Error Sets#}. 4458 </p> 4459 {#header_open|The Global Error Set#} 4460 <p>{#syntax#}anyerror{#endsyntax#} refers to the global error set. 4461 This is the error set that contains all errors in the entire compilation unit. 4462 It is a superset of all other error sets and a subset of none of them. 4463 </p> 4464 <p> 4465 You can {#link|coerce|Type Coercion#} any error set to the global one, and you can explicitly 4466 cast an error of the global error set to a non-global one. This inserts a language-level 4467 assert to make sure the error value is in fact in the destination error set. 4468 </p> 4469 <p> 4470 The global error set should generally be avoided because it prevents the 4471 compiler from knowing what errors are possible at compile-time. Knowing 4472 the error set at compile-time is better for generated documentation and 4473 helpful error messages, such as forgetting a possible error value in a {#link|switch#}. 4474 </p> 4475 {#header_close#} 4476 {#header_close#} 4477 {#header_open|Error Union Type#} 4478 <p> 4479 An error set type and normal type can be combined with the {#syntax#}!{#endsyntax#} 4480 binary operator to form an error union type. You are likely to use an 4481 error union type more often than an error set type by itself. 4482 </p> 4483 <p> 4484 Here is a function to parse a string into a 64-bit integer: 4485 </p> 4486 {#code_begin|test#} 4487 const std = @import("std"); 4488 const maxInt = std.math.maxInt; 4489 4490 pub fn parseU64(buf: []const u8, radix: u8) !u64 { 4491 var x: u64 = 0; 4492 4493 for (buf) |c| { 4494 const digit = charToDigit(c); 4495 4496 if (digit >= radix) { 4497 return error.InvalidChar; 4498 } 4499 4500 // x *= radix 4501 if (@mulWithOverflow(u64, x, radix, &x)) { 4502 return error.Overflow; 4503 } 4504 4505 // x += digit 4506 if (@addWithOverflow(u64, x, digit, &x)) { 4507 return error.Overflow; 4508 } 4509 } 4510 4511 return x; 4512 } 4513 4514 fn charToDigit(c: u8) u8 { 4515 return switch (c) { 4516 '0' ... '9' => c - '0', 4517 'A' ... 'Z' => c - 'A' + 10, 4518 'a' ... 'z' => c - 'a' + 10, 4519 else => maxInt(u8), 4520 }; 4521 } 4522 4523 test "parse u64" { 4524 const result = try parseU64("1234", 10); 4525 try std.testing.expect(result == 1234); 4526 } 4527 {#code_end#} 4528 <p> 4529 Notice the return type is {#syntax#}!u64{#endsyntax#}. This means that the function 4530 either returns an unsigned 64 bit integer, or an error. We left off the error set 4531 to the left of the {#syntax#}!{#endsyntax#}, so the error set is inferred. 4532 </p> 4533 <p> 4534 Within the function definition, you can see some return statements that return 4535 an error, and at the bottom a return statement that returns a {#syntax#}u64{#endsyntax#}. 4536 Both types {#link|coerce|Type Coercion#} to {#syntax#}anyerror!u64{#endsyntax#}. 4537 </p> 4538 <p> 4539 What it looks like to use this function varies depending on what you're 4540 trying to do. One of the following: 4541 </p> 4542 <ul> 4543 <li>You want to provide a default value if it returned an error.</li> 4544 <li>If it returned an error then you want to return the same error.</li> 4545 <li>You know with complete certainty it will not return an error, so want to unconditionally unwrap it.</li> 4546 <li>You want to take a different action for each possible error.</li> 4547 </ul> 4548 {#header_open|catch#} 4549 <p>If you want to provide a default value, you can use the {#syntax#}catch{#endsyntax#} binary operator:</p> 4550 {#code_begin|syntax#} 4551 fn doAThing(str: []u8) void { 4552 const number = parseU64(str, 10) catch 13; 4553 // ... 4554 } 4555 {#code_end#} 4556 <p> 4557 In this code, {#syntax#}number{#endsyntax#} will be equal to the successfully parsed string, or 4558 a default value of 13. The type of the right hand side of the binary {#syntax#}catch{#endsyntax#} operator must 4559 match the unwrapped error union type, or be of type {#syntax#}noreturn{#endsyntax#}. 4560 </p> 4561 {#header_close#} 4562 {#header_open|try#} 4563 <p>Let's say you wanted to return the error if you got one, otherwise continue with the 4564 function logic:</p> 4565 {#code_begin|syntax#} 4566 fn doAThing(str: []u8) !void { 4567 const number = parseU64(str, 10) catch |err| return err; 4568 // ... 4569 } 4570 {#code_end#} 4571 <p> 4572 There is a shortcut for this. The {#syntax#}try{#endsyntax#} expression: 4573 </p> 4574 {#code_begin|syntax#} 4575 fn doAThing(str: []u8) !void { 4576 const number = try parseU64(str, 10); 4577 // ... 4578 } 4579 {#code_end#} 4580 <p> 4581 {#syntax#}try{#endsyntax#} evaluates an error union expression. If it is an error, it returns 4582 from the current function with the same error. Otherwise, the expression results in 4583 the unwrapped value. 4584 </p> 4585 {#header_close#} 4586 <p> 4587 Maybe you know with complete certainty that an expression will never be an error. 4588 In this case you can do this: 4589 </p> 4590 {#code_begin|syntax#}const number = parseU64("1234", 10) catch unreachable;{#code_end#} 4591 <p> 4592 Here we know for sure that "1234" will parse successfully. So we put the 4593 {#syntax#}unreachable{#endsyntax#} value on the right hand side. {#syntax#}unreachable{#endsyntax#} generates 4594 a panic in Debug and ReleaseSafe modes and undefined behavior in ReleaseFast mode. So, while we're debugging the 4595 application, if there <em>was</em> a surprise error here, the application would crash 4596 appropriately. 4597 </p> 4598 <p> 4599 Finally, you may want to take a different action for every situation. For that, we combine 4600 the {#link|if#} and {#link|switch#} expression: 4601 </p> 4602 {#code_begin|syntax#} 4603 fn doAThing(str: []u8) void { 4604 if (parseU64(str, 10)) |number| { 4605 doSomethingWithNumber(number); 4606 } else |err| switch (err) { 4607 error.Overflow => { 4608 // handle overflow... 4609 }, 4610 // we promise that InvalidChar won't happen (or crash in debug mode if it does) 4611 error.InvalidChar => unreachable, 4612 } 4613 } 4614 {#code_end#} 4615 {#header_open|errdefer#} 4616 <p> 4617 The other component to error handling is defer statements. 4618 In addition to an unconditional {#link|defer#}, Zig has {#syntax#}errdefer{#endsyntax#}, 4619 which evaluates the deferred expression on block exit path if and only if 4620 the function returned with an error from the block. 4621 </p> 4622 <p> 4623 Example: 4624 </p> 4625 {#code_begin|syntax#} 4626 fn createFoo(param: i32) !Foo { 4627 const foo = try tryToAllocateFoo(); 4628 // now we have allocated foo. we need to free it if the function fails. 4629 // but we want to return it if the function succeeds. 4630 errdefer deallocateFoo(foo); 4631 4632 const tmp_buf = allocateTmpBuffer() orelse return error.OutOfMemory; 4633 // tmp_buf is truly a temporary resource, and we for sure want to clean it up 4634 // before this block leaves scope 4635 defer deallocateTmpBuffer(tmp_buf); 4636 4637 if (param > 1337) return error.InvalidParam; 4638 4639 // here the errdefer will not run since we're returning success from the function. 4640 // but the defer will run! 4641 return foo; 4642 } 4643 {#code_end#} 4644 <p> 4645 The neat thing about this is that you get robust error handling without 4646 the verbosity and cognitive overhead of trying to make sure every exit path 4647 is covered. The deallocation code is always directly following the allocation code. 4648 </p> 4649 {#header_close#} 4650 <p> 4651 A couple of other tidbits about error handling: 4652 </p> 4653 <ul> 4654 <li>These primitives give enough expressiveness that it's completely practical 4655 to have failing to check for an error be a compile error. If you really want 4656 to ignore the error, you can add {#syntax#}catch unreachable{#endsyntax#} and 4657 get the added benefit of crashing in Debug and ReleaseSafe modes if your assumption was wrong. 4658 </li> 4659 <li> 4660 Since Zig understands error types, it can pre-weight branches in favor of 4661 errors not occurring. Just a small optimization benefit that is not available 4662 in other languages. 4663 </li> 4664 </ul> 4665 {#see_also|defer|if|switch#} 4666 4667 <p>An error union is created with the {#syntax#}!{#endsyntax#} binary operator. 4668 You can use compile-time reflection to access the child type of an error union:</p> 4669 {#code_begin|test#} 4670 const expect = @import("std").testing.expect; 4671 4672 test "error union" { 4673 var foo: anyerror!i32 = undefined; 4674 4675 // Coerce from child type of an error union: 4676 foo = 1234; 4677 4678 // Coerce from an error set: 4679 foo = error.SomeError; 4680 4681 // Use compile-time reflection to access the payload type of an error union: 4682 comptime try expect(@typeInfo(@TypeOf(foo)).ErrorUnion.payload == i32); 4683 4684 // Use compile-time reflection to access the error set type of an error union: 4685 comptime try expect(@typeInfo(@TypeOf(foo)).ErrorUnion.error_set == anyerror); 4686 } 4687 {#code_end#} 4688 {#header_open|Merging Error Sets#} 4689 <p> 4690 Use the {#syntax#}||{#endsyntax#} operator to merge two error sets together. The resulting 4691 error set contains the errors of both error sets. Doc comments from the left-hand 4692 side override doc comments from the right-hand side. In this example, the doc 4693 comments for {#syntax#}C.PathNotFound{#endsyntax#} is <code>A doc comment</code>. 4694 </p> 4695 <p> 4696 This is especially useful for functions which return different error sets depending 4697 on {#link|comptime#} branches. For example, the Zig standard library uses 4698 {#syntax#}LinuxFileOpenError || WindowsFileOpenError{#endsyntax#} for the error set of opening 4699 files. 4700 </p> 4701 {#code_begin|test#} 4702 const A = error{ 4703 NotDir, 4704 4705 /// A doc comment 4706 PathNotFound, 4707 }; 4708 const B = error{ 4709 OutOfMemory, 4710 4711 /// B doc comment 4712 PathNotFound, 4713 }; 4714 4715 const C = A || B; 4716 4717 fn foo() C!void { 4718 return error.NotDir; 4719 } 4720 4721 test "merge error sets" { 4722 if (foo()) { 4723 @panic("unexpected"); 4724 } else |err| switch (err) { 4725 error.OutOfMemory => @panic("unexpected"), 4726 error.PathNotFound => @panic("unexpected"), 4727 error.NotDir => {}, 4728 } 4729 } 4730 {#code_end#} 4731 {#header_close#} 4732 {#header_open|Inferred Error Sets#} 4733 <p> 4734 Because many functions in Zig return a possible error, Zig supports inferring the error set. 4735 To infer the error set for a function, use this syntax: 4736 </p> 4737 {#code_begin|test#} 4738 // With an inferred error set 4739 pub fn add_inferred(comptime T: type, a: T, b: T) !T { 4740 var answer: T = undefined; 4741 return if (@addWithOverflow(T, a, b, &answer)) error.Overflow else answer; 4742 } 4743 4744 // With an explicit error set 4745 pub fn add_explicit(comptime T: type, a: T, b: T) Error!T { 4746 var answer: T = undefined; 4747 return if (@addWithOverflow(T, a, b, &answer)) error.Overflow else answer; 4748 } 4749 4750 const Error = error { 4751 Overflow, 4752 }; 4753 4754 const std = @import("std"); 4755 4756 test "inferred error set" { 4757 if (add_inferred(u8, 255, 1)) |_| unreachable else |err| switch (err) { 4758 error.Overflow => {}, // ok 4759 } 4760 } 4761 {#code_end#} 4762 <p> 4763 When a function has an inferred error set, that function becomes generic and thus it becomes 4764 trickier to do certain things with it, such as obtain a function pointer, or have an error 4765 set that is consistent across different build targets. Additionally, inferred error sets 4766 are incompatible with recursion. 4767 </p> 4768 <p> 4769 In these situations, it is recommended to use an explicit error set. You can generally start 4770 with an empty error set and let compile errors guide you toward completing the set. 4771 </p> 4772 <p> 4773 These limitations may be overcome in a future version of Zig. 4774 </p> 4775 {#header_close#} 4776 {#header_close#} 4777 {#header_open|Error Return Traces#} 4778 <p> 4779 Error Return Traces show all the points in the code that an error was returned to the calling function. This makes it practical to use {#link|try#} everywhere and then still be able to know what happened if an error ends up bubbling all the way out of your application. 4780 </p> 4781 {#code_begin|exe_err#} 4782 pub fn main() !void { 4783 try foo(12); 4784 } 4785 4786 fn foo(x: i32) !void { 4787 if (x >= 5) { 4788 try bar(); 4789 } else { 4790 try bang2(); 4791 } 4792 } 4793 4794 fn bar() !void { 4795 if (baz()) { 4796 try quux(); 4797 } else |err| switch (err) { 4798 error.FileNotFound => try hello(), 4799 else => try another(), 4800 } 4801 } 4802 4803 fn baz() !void { 4804 try bang1(); 4805 } 4806 4807 fn quux() !void { 4808 try bang2(); 4809 } 4810 4811 fn hello() !void { 4812 try bang2(); 4813 } 4814 4815 fn another() !void { 4816 try bang1(); 4817 } 4818 4819 fn bang1() !void { 4820 return error.FileNotFound; 4821 } 4822 4823 fn bang2() !void { 4824 return error.PermissionDenied; 4825 } 4826 {#code_end#} 4827 <p> 4828 Look closely at this example. This is no stack trace. 4829 </p> 4830 <p> 4831 You can see that the final error bubbled up was {#syntax#}PermissionDenied{#endsyntax#}, 4832 but the original error that started this whole thing was {#syntax#}FileNotFound{#endsyntax#}. In the {#syntax#}bar{#endsyntax#} function, the code handles the original error code, 4833 and then returns another one, from the switch statement. Error Return Traces make this clear, whereas a stack trace would look like this: 4834 </p> 4835 {#code_begin|exe_err#} 4836 pub fn main() void { 4837 foo(12); 4838 } 4839 4840 fn foo(x: i32) void { 4841 if (x >= 5) { 4842 bar(); 4843 } else { 4844 bang2(); 4845 } 4846 } 4847 4848 fn bar() void { 4849 if (baz()) { 4850 quux(); 4851 } else { 4852 hello(); 4853 } 4854 } 4855 4856 fn baz() bool { 4857 return bang1(); 4858 } 4859 4860 fn quux() void { 4861 bang2(); 4862 } 4863 4864 fn hello() void { 4865 bang2(); 4866 } 4867 4868 fn bang1() bool { 4869 return false; 4870 } 4871 4872 fn bang2() void { 4873 @panic("PermissionDenied"); 4874 } 4875 {#code_end#} 4876 <p> 4877 Here, the stack trace does not explain how the control 4878 flow in {#syntax#}bar{#endsyntax#} got to the {#syntax#}hello(){#endsyntax#} call. 4879 One would have to open a debugger or further instrument the application 4880 in order to find out. The error return trace, on the other hand, 4881 shows exactly how the error bubbled up. 4882 </p> 4883 <p> 4884 This debugging feature makes it easier to iterate quickly on code that 4885 robustly handles all error conditions. This means that Zig developers 4886 will naturally find themselves writing correct, robust code in order 4887 to increase their development pace. 4888 </p> 4889 <p> 4890 Error Return Traces are enabled by default in {#link|Debug#} and {#link|ReleaseSafe#} builds and disabled by default in {#link|ReleaseFast#} and {#link|ReleaseSmall#} builds. 4891 </p> 4892 <p> 4893 There are a few ways to activate this error return tracing feature: 4894 </p> 4895 <ul> 4896 <li>Return an error from main</li> 4897 <li>An error makes its way to {#syntax#}catch unreachable{#endsyntax#} and you have not overridden the default panic handler</li> 4898 <li>Use {#link|errorReturnTrace#} to access the current return trace. You can use {#syntax#}std.debug.dumpStackTrace{#endsyntax#} to print it. This function returns comptime-known {#link|null#} when building without error return tracing support.</li> 4899 </ul> 4900 {#header_open|Implementation Details#} 4901 <p> 4902 To analyze performance cost, there are two cases: 4903 </p> 4904 <ul> 4905 <li>when no errors are returned</li> 4906 <li>when returning errors</li> 4907 </ul> 4908 <p> 4909 For the case when no errors are returned, the cost is a single memory write operation, only in the first non-failable function in the call graph that calls a failable function, i.e. when a function returning {#syntax#}void{#endsyntax#} calls a function returning {#syntax#}error{#endsyntax#}. 4910 This is to initialize this struct in the stack memory: 4911 </p> 4912 {#code_begin|syntax#} 4913 pub const StackTrace = struct { 4914 index: usize, 4915 instruction_addresses: [N]usize, 4916 }; 4917 {#code_end#} 4918 <p> 4919 Here, N is the maximum function call depth as determined by call graph analysis. Recursion is ignored and counts for 2. 4920 </p> 4921 <p> 4922 A pointer to {#syntax#}StackTrace{#endsyntax#} is passed as a secret parameter to every function that can return an error, but it's always the first parameter, so it can likely sit in a register and stay there. 4923 </p> 4924 <p> 4925 That's it for the path when no errors occur. It's practically free in terms of performance. 4926 </p> 4927 <p> 4928 When generating the code for a function that returns an error, just before the {#syntax#}return{#endsyntax#} statement (only for the {#syntax#}return{#endsyntax#} statements that return errors), Zig generates a call to this function: 4929 </p> 4930 {#code_begin|syntax#} 4931 // marked as "no-inline" in LLVM IR 4932 fn __zig_return_error(stack_trace: *StackTrace) void { 4933 stack_trace.instruction_addresses[stack_trace.index] = @returnAddress(); 4934 stack_trace.index = (stack_trace.index + 1) % N; 4935 } 4936 {#code_end#} 4937 <p> 4938 The cost is 2 math operations plus some memory reads and writes. The memory accessed is constrained and should remain cached for the duration of the error return bubbling. 4939 </p> 4940 <p> 4941 As for code size cost, 1 function call before a return statement is no big deal. Even so, 4942 I have <a href="https://github.com/ziglang/zig/issues/690">a plan</a> to make the call to 4943 {#syntax#}__zig_return_error{#endsyntax#} a tail call, which brings the code size cost down to actually zero. What is a return statement in code without error return tracing can become a jump instruction in code with error return tracing. 4944 </p> 4945 {#header_close#} 4946 {#header_close#} 4947 {#header_close#} 4948 {#header_open|Optionals#} 4949 <p> 4950 One area that Zig provides safety without compromising efficiency or 4951 readability is with the optional type. 4952 </p> 4953 <p> 4954 The question mark symbolizes the optional type. You can convert a type to an optional 4955 type by putting a question mark in front of it, like this: 4956 </p> 4957 {#code_begin|syntax#} 4958 // normal integer 4959 const normal_int: i32 = 1234; 4960 4961 // optional integer 4962 const optional_int: ?i32 = 5678; 4963 {#code_end#} 4964 <p> 4965 Now the variable {#syntax#}optional_int{#endsyntax#} could be an {#syntax#}i32{#endsyntax#}, or {#syntax#}null{#endsyntax#}. 4966 </p> 4967 <p> 4968 Instead of integers, let's talk about pointers. Null references are the source of many runtime 4969 exceptions, and even stand accused of being 4970 <a href="https://www.lucidchart.com/techblog/2015/08/31/the-worst-mistake-of-computer-science/">the worst mistake of computer science</a>. 4971 </p> 4972 <p>Zig does not have them.</p> 4973 <p> 4974 Instead, you can use an optional pointer. This secretly compiles down to a normal pointer, 4975 since we know we can use 0 as the null value for the optional type. But the compiler 4976 can check your work and make sure you don't assign null to something that can't be null. 4977 </p> 4978 <p> 4979 Typically the downside of not having null is that it makes the code more verbose to 4980 write. But, let's compare some equivalent C code and Zig code. 4981 </p> 4982 <p> 4983 Task: call malloc, if the result is null, return null. 4984 </p> 4985 <p>C code</p> 4986 <pre><code class="cpp">// malloc prototype included for reference 4987 void *malloc(size_t size); 4988 4989 struct Foo *do_a_thing(void) { 4990 char *ptr = malloc(1234); 4991 if (!ptr) return NULL; 4992 // ... 4993 }</code></pre> 4994 <p>Zig code</p> 4995 {#code_begin|syntax#} 4996 // malloc prototype included for reference 4997 extern fn malloc(size: size_t) ?*u8; 4998 4999 fn doAThing() ?*Foo { 5000 const ptr = malloc(1234) orelse return null; 5001 // ... 5002 } 5003 {#code_end#} 5004 <p> 5005 Here, Zig is at least as convenient, if not more, than C. And, the type of "ptr" 5006 is {#syntax#}*u8{#endsyntax#} <em>not</em> {#syntax#}?*u8{#endsyntax#}. The {#syntax#}orelse{#endsyntax#} keyword 5007 unwrapped the optional type and therefore {#syntax#}ptr{#endsyntax#} is guaranteed to be non-null everywhere 5008 it is used in the function. 5009 </p> 5010 <p> 5011 The other form of checking against NULL you might see looks like this: 5012 </p> 5013 <pre><code class="cpp">void do_a_thing(struct Foo *foo) { 5014 // do some stuff 5015 5016 if (foo) { 5017 do_something_with_foo(foo); 5018 } 5019 5020 // do some stuff 5021 }</code></pre> 5022 <p> 5023 In Zig you can accomplish the same thing: 5024 </p> 5025 {#code_begin|syntax#} 5026 fn doAThing(optional_foo: ?*Foo) void { 5027 // do some stuff 5028 5029 if (optional_foo) |foo| { 5030 doSomethingWithFoo(foo); 5031 } 5032 5033 // do some stuff 5034 } 5035 {#code_end#} 5036 <p> 5037 Once again, the notable thing here is that inside the if block, 5038 {#syntax#}foo{#endsyntax#} is no longer an optional pointer, it is a pointer, which 5039 cannot be null. 5040 </p> 5041 <p> 5042 One benefit to this is that functions which take pointers as arguments can 5043 be annotated with the "nonnull" attribute - <code>__attribute__((nonnull))</code> in 5044 <a href="https://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Function-Attributes.html">GCC</a>. 5045 The optimizer can sometimes make better decisions knowing that pointer arguments 5046 cannot be null. 5047 </p> 5048 {#header_open|Optional Type#} 5049 <p>An optional is created by putting {#syntax#}?{#endsyntax#} in front of a type. You can use compile-time 5050 reflection to access the child type of an optional:</p> 5051 {#code_begin|test#} 5052 const expect = @import("std").testing.expect; 5053 5054 test "optional type" { 5055 // Declare an optional and coerce from null: 5056 var foo: ?i32 = null; 5057 5058 // Coerce from child type of an optional 5059 foo = 1234; 5060 5061 // Use compile-time reflection to access the child type of the optional: 5062 comptime try expect(@typeInfo(@TypeOf(foo)).Optional.child == i32); 5063 } 5064 {#code_end#} 5065 {#header_close#} 5066 {#header_open|null#} 5067 <p> 5068 Just like {#link|undefined#}, {#syntax#}null{#endsyntax#} has its own type, and the only way to use it is to 5069 cast it to a different type: 5070 </p> 5071 {#code_begin|syntax#} 5072 const optional_value: ?i32 = null; 5073 {#code_end#} 5074 {#header_close#} 5075 {#header_open|Optional Pointers#} 5076 <p>An optional pointer is guaranteed to be the same size as a pointer. The {#syntax#}null{#endsyntax#} of 5077 the optional is guaranteed to be address 0.</p> 5078 {#code_begin|test#} 5079 const expect = @import("std").testing.expect; 5080 5081 test "optional pointers" { 5082 // Pointers cannot be null. If you want a null pointer, use the optional 5083 // prefix `?` to make the pointer type optional. 5084 var ptr: ?*i32 = null; 5085 5086 var x: i32 = 1; 5087 ptr = &x; 5088 5089 try expect(ptr.?.* == 1); 5090 5091 // Optional pointers are the same size as normal pointers, because pointer 5092 // value 0 is used as the null value. 5093 try expect(@sizeOf(?*i32) == @sizeOf(*i32)); 5094 } 5095 {#code_end#} 5096 {#header_close#} 5097 {#header_close#} 5098 {#header_open|Casting#} 5099 <p> 5100 A <strong>type cast</strong> converts a value of one type to another. 5101 Zig has {#link|Type Coercion#} for conversions that are known to be completely safe and unambiguous, 5102 and {#link|Explicit Casts#} for conversions that one would not want to happen on accident. 5103 There is also a third kind of type conversion called {#link|Peer Type Resolution#} for 5104 the case when a result type must be decided given multiple operand types. 5105 </p> 5106 {#header_open|Type Coercion#} 5107 <p> 5108 Type coercion occurs when one type is expected, but different type is provided: 5109 </p> 5110 {#code_begin|test#} 5111 test "type coercion - variable declaration" { 5112 var a: u8 = 1; 5113 var b: u16 = a; 5114 } 5115 5116 test "type coercion - function call" { 5117 var a: u8 = 1; 5118 foo(a); 5119 } 5120 5121 fn foo(b: u16) void {} 5122 5123 test "type coercion - @as builtin" { 5124 var a: u8 = 1; 5125 var b = @as(u16, a); 5126 } 5127 {#code_end#} 5128 <p> 5129 Type coercions are only allowed when it is completely unambiguous how to get from one type to another, 5130 and the transformation is guaranteed to be safe. There is one exception, which is {#link|C Pointers#}. 5131 </p> 5132 {#header_open|Type Coercion: Stricter Qualification#} 5133 <p> 5134 Values which have the same representation at runtime can be cast to increase the strictness 5135 of the qualifiers, no matter how nested the qualifiers are: 5136 </p> 5137 <ul> 5138 <li>{#syntax#}const{#endsyntax#} - non-const to const is allowed</li> 5139 <li>{#syntax#}volatile{#endsyntax#} - non-volatile to volatile is allowed</li> 5140 <li>{#syntax#}align{#endsyntax#} - bigger to smaller alignment is allowed </li> 5141 <li>{#link|error sets|Error Set Type#} to supersets is allowed</li> 5142 </ul> 5143 <p> 5144 These casts are no-ops at runtime since the value representation does not change. 5145 </p> 5146 {#code_begin|test#} 5147 test "type coercion - const qualification" { 5148 var a: i32 = 1; 5149 var b: *i32 = &a; 5150 foo(b); 5151 } 5152 5153 fn foo(a: *const i32) void {} 5154 {#code_end#} 5155 <p> 5156 In addition, pointers coerce to const optional pointers: 5157 </p> 5158 {#code_begin|test#} 5159 const std = @import("std"); 5160 const expect = std.testing.expect; 5161 const mem = std.mem; 5162 5163 test "cast *[1][*]const u8 to [*]const ?[*]const u8" { 5164 const window_name = [1][*]const u8{"window name"}; 5165 const x: [*]const ?[*]const u8 = &window_name; 5166 try expect(mem.eql(u8, std.mem.spanZ(@ptrCast([*:0]const u8, x[0].?)), "window name")); 5167 } 5168 {#code_end#} 5169 {#header_close#} 5170 {#header_open|Type Coercion: Integer and Float Widening#} 5171 <p> 5172 {#link|Integers#} coerce to integer types which can represent every value of the old type, and likewise 5173 {#link|Floats#} coerce to float types which can represent every value of the old type. 5174 </p> 5175 {#code_begin|test#} 5176 const std = @import("std"); 5177 const expect = std.testing.expect; 5178 const mem = std.mem; 5179 5180 test "integer widening" { 5181 var a: u8 = 250; 5182 var b: u16 = a; 5183 var c: u32 = b; 5184 var d: u64 = c; 5185 var e: u64 = d; 5186 var f: u128 = e; 5187 try expect(f == a); 5188 } 5189 5190 test "implicit unsigned integer to signed integer" { 5191 var a: u8 = 250; 5192 var b: i16 = a; 5193 try expect(b == 250); 5194 } 5195 5196 test "float widening" { 5197 // Note: there is an open issue preventing this from working on aarch64: 5198 // https://github.com/ziglang/zig/issues/3282 5199 if (std.Target.current.cpu.arch == .aarch64) return error.SkipZigTest; 5200 5201 var a: f16 = 12.34; 5202 var b: f32 = a; 5203 var c: f64 = b; 5204 var d: f128 = c; 5205 try expect(d == a); 5206 } 5207 {#code_end#} 5208 {#header_close#} 5209 {#header_open|Type Coercion: Coercion Float to Int#} 5210 <p> 5211 A compiler error is appropriate because this ambiguous expression leaves the compiler 5212 two choices about the coercion. 5213 </p> 5214 <ul> 5215 <li> Cast {#syntax#}54.0{#endsyntax#} to {#syntax#}comptime_int{#endsyntax#} resulting in {#syntax#}@as(comptime_int, 10){#endsyntax#}, which is casted to {#syntax#}@as(f32, 10){#endsyntax#}</li> 5216 <li> Cast {#syntax#}5{#endsyntax#} to {#syntax#}comptime_float{#endsyntax#} resulting in {#syntax#}@as(comptime_float, 10.8){#endsyntax#}, which is casted to {#syntax#}@as(f32, 10.8){#endsyntax#}</li> 5217 </ul> 5218 {#code_begin|test_err#} 5219 // Compile time coercion of float to int 5220 test "implicit cast to comptime_int" { 5221 var f: f32 = 54.0 / 5; 5222 } 5223 {#code_end#} 5224 {#header_close#} 5225 {#header_open|Type Coercion: Arrays and Pointers#} 5226 {#code_begin|test|coerce_arrays_and_ptrs#} 5227 const std = @import("std"); 5228 const expect = std.testing.expect; 5229 5230 // This cast exists primarily so that string literals can be 5231 // passed to functions that accept const slices. However 5232 // it is probably going to be removed from the language when 5233 // https://github.com/ziglang/zig/issues/265 is implemented. 5234 test "[N]T to []const T" { 5235 var x1: []const u8 = "hello"; 5236 var x2: []const u8 = &[5]u8{ 'h', 'e', 'l', 'l', 111 }; 5237 try expect(std.mem.eql(u8, x1, x2)); 5238 5239 var y: []const f32 = &[2]f32{ 1.2, 3.4 }; 5240 try expect(y[0] == 1.2); 5241 } 5242 5243 // Likewise, it works when the destination type is an error union. 5244 test "[N]T to E![]const T" { 5245 var x1: anyerror![]const u8 = "hello"; 5246 var x2: anyerror![]const u8 = &[5]u8{ 'h', 'e', 'l', 'l', 111 }; 5247 try expect(std.mem.eql(u8, try x1, try x2)); 5248 5249 var y: anyerror![]const f32 = &[2]f32{ 1.2, 3.4 }; 5250 try expect((try y)[0] == 1.2); 5251 } 5252 5253 // Likewise, it works when the destination type is an optional. 5254 test "[N]T to ?[]const T" { 5255 var x1: ?[]const u8 = "hello"; 5256 var x2: ?[]const u8 = &[5]u8{ 'h', 'e', 'l', 'l', 111 }; 5257 try expect(std.mem.eql(u8, x1.?, x2.?)); 5258 5259 var y: ?[]const f32 = &[2]f32{ 1.2, 3.4 }; 5260 try expect(y.?[0] == 1.2); 5261 } 5262 5263 // In this cast, the array length becomes the slice length. 5264 test "*[N]T to []T" { 5265 var buf: [5]u8 = "hello".*; 5266 const x: []u8 = &buf; 5267 try expect(std.mem.eql(u8, x, "hello")); 5268 5269 const buf2 = [2]f32{ 1.2, 3.4 }; 5270 const x2: []const f32 = &buf2; 5271 try expect(std.mem.eql(f32, x2, &[2]f32{ 1.2, 3.4 })); 5272 } 5273 5274 // Single-item pointers to arrays can be coerced to many-item pointers. 5275 test "*[N]T to [*]T" { 5276 var buf: [5]u8 = "hello".*; 5277 const x: [*]u8 = &buf; 5278 try expect(x[4] == 'o'); 5279 // x[5] would be an uncaught out of bounds pointer dereference! 5280 } 5281 5282 // Likewise, it works when the destination type is an optional. 5283 test "*[N]T to ?[*]T" { 5284 var buf: [5]u8 = "hello".*; 5285 const x: ?[*]u8 = &buf; 5286 try expect(x.?[4] == 'o'); 5287 } 5288 5289 // Single-item pointers can be cast to len-1 single-item arrays. 5290 test "*T to *[1]T" { 5291 var x: i32 = 1234; 5292 const y: *[1]i32 = &x; 5293 const z: [*]i32 = y; 5294 try expect(z[0] == 1234); 5295 } 5296 {#code_end#} 5297 {#see_also|C Pointers#} 5298 {#header_close#} 5299 {#header_open|Type Coercion: Optionals#} 5300 <p> 5301 The payload type of {#link|Optionals#}, as well as {#link|null#}, coerce to the optional type. 5302 </p> 5303 {#code_begin|test#} 5304 const std = @import("std"); 5305 const expect = std.testing.expect; 5306 5307 test "coerce to optionals" { 5308 const x: ?i32 = 1234; 5309 const y: ?i32 = null; 5310 5311 try expect(x.? == 1234); 5312 try expect(y == null); 5313 } 5314 {#code_end#} 5315 <p>It works nested inside the {#link|Error Union Type#}, too:</p> 5316 {#code_begin|test#} 5317 const std = @import("std"); 5318 const expect = std.testing.expect; 5319 5320 test "coerce to optionals wrapped in error union" { 5321 const x: anyerror!?i32 = 1234; 5322 const y: anyerror!?i32 = null; 5323 5324 try expect((try x).? == 1234); 5325 try expect((try y) == null); 5326 } 5327 {#code_end#} 5328 {#header_close#} 5329 {#header_open|Type Coercion: Error Unions#} 5330 <p>The payload type of an {#link|Error Union Type#} as well as the {#link|Error Set Type#} 5331 coerce to the error union type: 5332 </p> 5333 {#code_begin|test#} 5334 const std = @import("std"); 5335 const expect = std.testing.expect; 5336 5337 test "coercion to error unions" { 5338 const x: anyerror!i32 = 1234; 5339 const y: anyerror!i32 = error.Failure; 5340 5341 try expect((try x) == 1234); 5342 try std.testing.expectError(error.Failure, y); 5343 } 5344 {#code_end#} 5345 {#header_close#} 5346 {#header_open|Type Coercion: Compile-Time Known Numbers#} 5347 <p>When a number is {#link|comptime#}-known to be representable in the destination type, 5348 it may be coerced: 5349 </p> 5350 {#code_begin|test#} 5351 const std = @import("std"); 5352 const expect = std.testing.expect; 5353 5354 test "coercing large integer type to smaller one when value is comptime known to fit" { 5355 const x: u64 = 255; 5356 const y: u8 = x; 5357 try expect(y == 255); 5358 } 5359 {#code_end#} 5360 {#header_close#} 5361 {#header_open|Type Coercion: unions and enums#} 5362 <p>Tagged unions can be coerced to enums, and enums can be coerced to tagged unions 5363 when they are {#link|comptime#}-known to be a field of the union that has only one possible value, such as 5364 {#link|void#}: 5365 </p> 5366 {#code_begin|test#} 5367 const std = @import("std"); 5368 const expect = std.testing.expect; 5369 5370 const E = enum { 5371 one, 5372 two, 5373 three, 5374 }; 5375 5376 const U = union(E) { 5377 one: i32, 5378 two: f32, 5379 three, 5380 }; 5381 5382 test "coercion between unions and enums" { 5383 var u = U{ .two = 12.34 }; 5384 var e: E = u; 5385 try expect(e == E.two); 5386 5387 const three = E.three; 5388 var another_u: U = three; 5389 try expect(another_u == E.three); 5390 } 5391 {#code_end#} 5392 {#see_also|union|enum#} 5393 {#header_close#} 5394 {#header_open|Type Coercion: Zero Bit Types#} 5395 <p>{#link|Zero Bit Types#} may be coerced to single-item {#link|Pointers#}, 5396 regardless of const.</p> 5397 <p>TODO document the reasoning for this</p> 5398 <p>TODO document whether vice versa should work and why</p> 5399 {#code_begin|test#} 5400 test "coercion of zero bit types" { 5401 var x: void = {}; 5402 var y: *void = x; 5403 //var z: void = y; // TODO 5404 } 5405 {#code_end#} 5406 {#header_close#} 5407 {#header_open|Type Coercion: undefined#} 5408 <p>{#link|undefined#} can be cast to any type.</p> 5409 {#header_close#} 5410 {#header_close#} 5411 5412 {#header_open|Explicit Casts#} 5413 <p> 5414 Explicit casts are performed via {#link|Builtin Functions#}. 5415 Some explicit casts are safe; some are not. 5416 Some explicit casts perform language-level assertions; some do not. 5417 Some explicit casts are no-ops at runtime; some are not. 5418 </p> 5419 <ul> 5420 <li>{#link|@bitCast#} - change type but maintain bit representation</li> 5421 <li>{#link|@alignCast#} - make a pointer have more alignment</li> 5422 <li>{#link|@boolToInt#} - convert true to 1 and false to 0</li> 5423 <li>{#link|@enumToInt#} - obtain the integer tag value of an enum or tagged union</li> 5424 <li>{#link|@errSetCast#} - convert to a smaller error set</li> 5425 <li>{#link|@errorToInt#} - obtain the integer value of an error code</li> 5426 <li>{#link|@floatCast#} - convert a larger float to a smaller float</li> 5427 <li>{#link|@floatToInt#} - obtain the integer part of a float value</li> 5428 <li>{#link|@intCast#} - convert between integer types</li> 5429 <li>{#link|@intToEnum#} - obtain an enum value based on its integer tag value</li> 5430 <li>{#link|@intToError#} - obtain an error code based on its integer value</li> 5431 <li>{#link|@intToFloat#} - convert an integer to a float value</li> 5432 <li>{#link|@intToPtr#} - convert an address to a pointer</li> 5433 <li>{#link|@ptrCast#} - convert between pointer types</li> 5434 <li>{#link|@ptrToInt#} - obtain the address of a pointer</li> 5435 <li>{#link|@truncate#} - convert between integer types, chopping off bits</li> 5436 </ul> 5437 {#header_close#} 5438 5439 {#header_open|Peer Type Resolution#} 5440 <p>Peer Type Resolution occurs in these places:</p> 5441 <ul> 5442 <li>{#link|switch#} expressions</li> 5443 <li>{#link|if#} expressions</li> 5444 <li>{#link|while#} expressions</li> 5445 <li>{#link|for#} expressions</li> 5446 <li>Multiple break statements in a block</li> 5447 <li>Some {#link|binary operations|Table of Operators#}</li> 5448 </ul> 5449 <p> 5450 This kind of type resolution chooses a type that all peer types can coerce into. Here are 5451 some examples: 5452 </p> 5453 {#code_begin|test|peer_type_resolution#} 5454 const std = @import("std"); 5455 const expect = std.testing.expect; 5456 const mem = std.mem; 5457 5458 test "peer resolve int widening" { 5459 var a: i8 = 12; 5460 var b: i16 = 34; 5461 var c = a + b; 5462 try expect(c == 46); 5463 try expect(@TypeOf(c) == i16); 5464 } 5465 5466 test "peer resolve arrays of different size to const slice" { 5467 try expect(mem.eql(u8, boolToStr(true), "true")); 5468 try expect(mem.eql(u8, boolToStr(false), "false")); 5469 comptime try expect(mem.eql(u8, boolToStr(true), "true")); 5470 comptime try expect(mem.eql(u8, boolToStr(false), "false")); 5471 } 5472 fn boolToStr(b: bool) []const u8 { 5473 return if (b) "true" else "false"; 5474 } 5475 5476 test "peer resolve array and const slice" { 5477 try testPeerResolveArrayConstSlice(true); 5478 comptime try testPeerResolveArrayConstSlice(true); 5479 } 5480 fn testPeerResolveArrayConstSlice(b: bool) !void { 5481 const value1 = if (b) "aoeu" else @as([]const u8, "zz"); 5482 const value2 = if (b) @as([]const u8, "zz") else "aoeu"; 5483 try expect(mem.eql(u8, value1, "aoeu")); 5484 try expect(mem.eql(u8, value2, "zz")); 5485 } 5486 5487 test "peer type resolution: ?T and T" { 5488 try expect(peerTypeTAndOptionalT(true, false).? == 0); 5489 try expect(peerTypeTAndOptionalT(false, false).? == 3); 5490 comptime { 5491 try expect(peerTypeTAndOptionalT(true, false).? == 0); 5492 try expect(peerTypeTAndOptionalT(false, false).? == 3); 5493 } 5494 } 5495 fn peerTypeTAndOptionalT(c: bool, b: bool) ?usize { 5496 if (c) { 5497 return if (b) null else @as(usize, 0); 5498 } 5499 5500 return @as(usize, 3); 5501 } 5502 5503 test "peer type resolution: *[0]u8 and []const u8" { 5504 try expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0); 5505 try expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1); 5506 comptime { 5507 try expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0); 5508 try expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1); 5509 } 5510 } 5511 fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 { 5512 if (a) { 5513 return &[_]u8{}; 5514 } 5515 5516 return slice[0..1]; 5517 } 5518 test "peer type resolution: *[0]u8, []const u8, and anyerror![]u8" { 5519 { 5520 var data = "hi".*; 5521 const slice = data[0..]; 5522 try expect((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0); 5523 try expect((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1); 5524 } 5525 comptime { 5526 var data = "hi".*; 5527 const slice = data[0..]; 5528 try expect((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0); 5529 try expect((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1); 5530 } 5531 } 5532 fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) anyerror![]u8 { 5533 if (a) { 5534 return &[_]u8{}; 5535 } 5536 5537 return slice[0..1]; 5538 } 5539 5540 test "peer type resolution: *const T and ?*T" { 5541 const a = @intToPtr(*const usize, 0x123456780); 5542 const b = @intToPtr(?*usize, 0x123456780); 5543 try expect(a == b); 5544 try expect(b == a); 5545 } 5546 {#code_end#} 5547 {#header_close#} 5548 {#header_close#} 5549 5550 {#header_open|Zero Bit Types#} 5551 <p>For some types, {#link|@sizeOf#} is 0:</p> 5552 <ul> 5553 <li>{#link|void#}</li> 5554 <li>The {#link|Integers#} {#syntax#}u0{#endsyntax#} and {#syntax#}i0{#endsyntax#}.</li> 5555 <li>{#link|Arrays#} and {#link|Vectors#} with len 0, or with an element type that is a zero bit type.</li> 5556 <li>An {#link|enum#} with only 1 tag.</li> 5557 <li>A {#link|struct#} with all fields being zero bit types.</li> 5558 <li>A {#link|union#} with only 1 field which is a zero bit type.</li> 5559 <li>{#link|Pointers to Zero Bit Types#} are themselves zero bit types.</li> 5560 </ul> 5561 <p> 5562 These types can only ever have one possible value, and thus 5563 require 0 bits to represent. Code that makes use of these types is 5564 not included in the final generated code: 5565 </p> 5566 {#code_begin|syntax#} 5567 export fn entry() void { 5568 var x: void = {}; 5569 var y: void = {}; 5570 x = y; 5571 } 5572 {#code_end#} 5573 <p>When this turns into machine code, there is no code generated in the 5574 body of {#syntax#}entry{#endsyntax#}, even in {#link|Debug#} mode. For example, on x86_64:</p> 5575 <pre><code>0000000000000010 <entry>: 5576 10: 55 push %rbp 5577 11: 48 89 e5 mov %rsp,%rbp 5578 14: 5d pop %rbp 5579 15: c3 retq </code></pre> 5580 <p>These assembly instructions do not have any code associated with the void values - 5581 they only perform the function call prologue and epilog.</p> 5582 5583 {#header_open|void#} 5584 <p> 5585 {#syntax#}void{#endsyntax#} can be useful for instantiating generic types. For example, given a 5586 {#syntax#}Map(Key, Value){#endsyntax#}, one can pass {#syntax#}void{#endsyntax#} for the {#syntax#}Value{#endsyntax#} 5587 type to make it into a {#syntax#}Set{#endsyntax#}: 5588 </p> 5589 {#code_begin|test#} 5590 const std = @import("std"); 5591 const expect = std.testing.expect; 5592 5593 test "turn HashMap into a set with void" { 5594 var map = std.AutoHashMap(i32, void).init(std.testing.allocator); 5595 defer map.deinit(); 5596 5597 try map.put(1, {}); 5598 try map.put(2, {}); 5599 5600 try expect(map.contains(2)); 5601 try expect(!map.contains(3)); 5602 5603 _ = map.remove(2); 5604 try expect(!map.contains(2)); 5605 } 5606 {#code_end#} 5607 <p>Note that this is different from using a dummy value for the hash map value. 5608 By using {#syntax#}void{#endsyntax#} as the type of the value, the hash map entry type has no value field, and 5609 thus the hash map takes up less space. Further, all the code that deals with storing and loading the 5610 value is deleted, as seen above. 5611 </p> 5612 <p> 5613 {#syntax#}void{#endsyntax#} is distinct from {#syntax#}c_void{#endsyntax#}, which is defined like this: 5614 {#syntax#}pub const c_void = opaque {};{#endsyntax#}. 5615 {#syntax#}void{#endsyntax#} has a known size of 0 bytes, and {#syntax#}c_void{#endsyntax#} has an unknown, but non-zero, size. 5616 </p> 5617 <p> 5618 Expressions of type {#syntax#}void{#endsyntax#} are the only ones whose value can be ignored. For example: 5619 </p> 5620 {#code_begin|test_err|expression value is ignored#} 5621 test "ignoring expression value" { 5622 foo(); 5623 } 5624 5625 fn foo() i32 { 5626 return 1234; 5627 } 5628 {#code_end#} 5629 <p>However, if the expression has type {#syntax#}void{#endsyntax#}, there will be no error. Function return values can also be explicitly ignored by assigning them to {#syntax#}_{#endsyntax#}. </p> 5630 {#code_begin|test#} 5631 test "void is ignored" { 5632 returnsVoid(); 5633 } 5634 5635 test "explicitly ignoring expression value" { 5636 _ = foo(); 5637 } 5638 5639 fn returnsVoid() void {} 5640 5641 fn foo() i32 { 5642 return 1234; 5643 } 5644 {#code_end#} 5645 {#header_close#} 5646 5647 {#header_open|Pointers to Zero Bit Types#} 5648 <p>Pointers to zero bit types also have zero bits. They always compare equal to each other:</p> 5649 {#code_begin|test#} 5650 const std = @import("std"); 5651 const expect = std.testing.expect; 5652 5653 test "pointer to empty struct" { 5654 const Empty = struct {}; 5655 var a = Empty{}; 5656 var b = Empty{}; 5657 var ptr_a = &a; 5658 var ptr_b = &b; 5659 comptime try expect(ptr_a == ptr_b); 5660 } 5661 {#code_end#} 5662 <p>The type being pointed to can only ever be one value; therefore loads and stores are 5663 never generated. {#link|ptrToInt#} and {#link|intToPtr#} are not allowed:</p> 5664 {#code_begin|test_err#} 5665 const Empty = struct {}; 5666 5667 test "@ptrToInt for pointer to zero bit type" { 5668 var a = Empty{}; 5669 _ = @ptrToInt(&a); 5670 } 5671 5672 test "@intToPtr for pointer to zero bit type" { 5673 _ = @intToPtr(*Empty, 0x1); 5674 } 5675 {#code_end#} 5676 {#header_close#} 5677 {#header_close#} 5678 5679 {#header_open|Result Location Semantics#} 5680 <p> 5681 <a href="https://github.com/ziglang/zig/issues/2809">TODO add documentation for this</a> 5682 </p> 5683 {#header_close#} 5684 5685 {#header_open|usingnamespace#} 5686 <p> 5687 {#syntax#}usingnamespace{#endsyntax#} is a top level declaration that imports all the public declarations of 5688 the operand, which must be a {#link|struct#}, {#link|union#}, or {#link|enum#}, into the current scope: 5689 </p> 5690 {#code_begin|test|usingnamespace#} 5691 usingnamespace @import("std"); 5692 5693 test "using std namespace" { 5694 try testing.expect(true); 5695 } 5696 {#code_end#} 5697 <p> 5698 Instead of the above pattern, it is generally recommended to explicitly alias individual declarations. 5699 However, {#syntax#}usingnamespace{#endsyntax#} has an important use case when organizing the public 5700 API of a file or package. For example, one might have <code>c.zig</code> with all of the 5701 {#link|C imports|Import from C Header File#}: 5702 </p> 5703 <pre>{#syntax#} 5704 pub usingnamespace @cImport({ 5705 @cInclude("epoxy/gl.h"); 5706 @cInclude("GLFW/glfw3.h"); 5707 @cDefine("STBI_ONLY_PNG", ""); 5708 @cDefine("STBI_NO_STDIO", ""); 5709 @cInclude("stb_image.h"); 5710 }); 5711 {#endsyntax#}</pre> 5712 <p> 5713 The above example demonstrates using {#syntax#}pub{#endsyntax#} to qualify the 5714 {#syntax#}usingnamespace{#endsyntax#} additionally makes the imported declarations 5715 {#syntax#}pub{#endsyntax#}. This can be used to forward declarations, giving precise control 5716 over what declarations a given file exposes. 5717 </p> 5718 {#header_close#} 5719 5720 {#header_open|comptime#} 5721 <p> 5722 Zig places importance on the concept of whether an expression is known at compile-time. 5723 There are a few different places this concept is used, and these building blocks are used 5724 to keep the language small, readable, and powerful. 5725 </p> 5726 {#header_open|Introducing the Compile-Time Concept#} 5727 {#header_open|Compile-Time Parameters#} 5728 <p> 5729 Compile-time parameters is how Zig implements generics. It is compile-time duck typing. 5730 </p> 5731 {#code_begin|syntax#} 5732 fn max(comptime T: type, a: T, b: T) T { 5733 return if (a > b) a else b; 5734 } 5735 fn gimmeTheBiggerFloat(a: f32, b: f32) f32 { 5736 return max(f32, a, b); 5737 } 5738 fn gimmeTheBiggerInteger(a: u64, b: u64) u64 { 5739 return max(u64, a, b); 5740 } 5741 {#code_end#} 5742 <p> 5743 In Zig, types are first-class citizens. They can be assigned to variables, passed as parameters to functions, 5744 and returned from functions. However, they can only be used in expressions which are known at <em>compile-time</em>, 5745 which is why the parameter {#syntax#}T{#endsyntax#} in the above snippet must be marked with {#syntax#}comptime{#endsyntax#}. 5746 </p> 5747 <p> 5748 A {#syntax#}comptime{#endsyntax#} parameter means that: 5749 </p> 5750 <ul> 5751 <li>At the callsite, the value must be known at compile-time, or it is a compile error.</li> 5752 <li>In the function definition, the value is known at compile-time.</li> 5753 </ul> 5754 <p> 5755 For example, if we were to introduce another function to the above snippet: 5756 </p> 5757 {#code_begin|test_err|values of type 'type' must be comptime known#} 5758 fn max(comptime T: type, a: T, b: T) T { 5759 return if (a > b) a else b; 5760 } 5761 test "try to pass a runtime type" { 5762 foo(false); 5763 } 5764 fn foo(condition: bool) void { 5765 const result = max( 5766 if (condition) f32 else u64, 5767 1234, 5768 5678); 5769 } 5770 {#code_end#} 5771 <p> 5772 This is an error because the programmer attempted to pass a value only known at run-time 5773 to a function which expects a value known at compile-time. 5774 </p> 5775 <p> 5776 Another way to get an error is if we pass a type that violates the type checker when the 5777 function is analyzed. This is what it means to have <em>compile-time duck typing</em>. 5778 </p> 5779 <p> 5780 For example: 5781 </p> 5782 {#code_begin|test_err|operator not allowed for type 'bool'#} 5783 fn max(comptime T: type, a: T, b: T) T { 5784 return if (a > b) a else b; 5785 } 5786 test "try to compare bools" { 5787 _ = max(bool, true, false); 5788 } 5789 {#code_end#} 5790 <p> 5791 On the flip side, inside the function definition with the {#syntax#}comptime{#endsyntax#} parameter, the 5792 value is known at compile-time. This means that we actually could make this work for the bool type 5793 if we wanted to: 5794 </p> 5795 {#code_begin|test#} 5796 fn max(comptime T: type, a: T, b: T) T { 5797 if (T == bool) { 5798 return a or b; 5799 } else if (a > b) { 5800 return a; 5801 } else { 5802 return b; 5803 } 5804 } 5805 test "try to compare bools" { 5806 try @import("std").testing.expect(max(bool, false, true) == true); 5807 } 5808 {#code_end#} 5809 <p> 5810 This works because Zig implicitly inlines {#syntax#}if{#endsyntax#} expressions when the condition 5811 is known at compile-time, and the compiler guarantees that it will skip analysis of 5812 the branch not taken. 5813 </p> 5814 <p> 5815 This means that the actual function generated for {#syntax#}max{#endsyntax#} in this situation looks like 5816 this: 5817 </p> 5818 {#code_begin|syntax#} 5819 fn max(a: bool, b: bool) bool { 5820 return a or b; 5821 } 5822 {#code_end#} 5823 <p> 5824 All the code that dealt with compile-time known values is eliminated and we are left with only 5825 the necessary run-time code to accomplish the task. 5826 </p> 5827 <p> 5828 This works the same way for {#syntax#}switch{#endsyntax#} expressions - they are implicitly inlined 5829 when the target expression is compile-time known. 5830 </p> 5831 {#header_close#} 5832 {#header_open|Compile-Time Variables#} 5833 <p> 5834 In Zig, the programmer can label variables as {#syntax#}comptime{#endsyntax#}. This guarantees to the compiler 5835 that every load and store of the variable is performed at compile-time. Any violation of this results in a 5836 compile error. 5837 </p> 5838 <p> 5839 This combined with the fact that we can {#syntax#}inline{#endsyntax#} loops allows us to write 5840 a function which is partially evaluated at compile-time and partially at run-time. 5841 </p> 5842 <p> 5843 For example: 5844 </p> 5845 {#code_begin|test|comptime_vars#} 5846 const expect = @import("std").testing.expect; 5847 5848 const CmdFn = struct { 5849 name: []const u8, 5850 func: fn(i32) i32, 5851 }; 5852 5853 const cmd_fns = [_]CmdFn{ 5854 CmdFn {.name = "one", .func = one}, 5855 CmdFn {.name = "two", .func = two}, 5856 CmdFn {.name = "three", .func = three}, 5857 }; 5858 fn one(value: i32) i32 { return value + 1; } 5859 fn two(value: i32) i32 { return value + 2; } 5860 fn three(value: i32) i32 { return value + 3; } 5861 5862 fn performFn(comptime prefix_char: u8, start_value: i32) i32 { 5863 var result: i32 = start_value; 5864 comptime var i = 0; 5865 inline while (i < cmd_fns.len) : (i += 1) { 5866 if (cmd_fns[i].name[0] == prefix_char) { 5867 result = cmd_fns[i].func(result); 5868 } 5869 } 5870 return result; 5871 } 5872 5873 test "perform fn" { 5874 try expect(performFn('t', 1) == 6); 5875 try expect(performFn('o', 0) == 1); 5876 try expect(performFn('w', 99) == 99); 5877 } 5878 {#code_end#} 5879 <p> 5880 This example is a bit contrived, because the compile-time evaluation component is unnecessary; 5881 this code would work fine if it was all done at run-time. But it does end up generating 5882 different code. In this example, the function {#syntax#}performFn{#endsyntax#} is generated three different times, 5883 for the different values of {#syntax#}prefix_char{#endsyntax#} provided: 5884 </p> 5885 {#code_begin|syntax#} 5886 // From the line: 5887 // expect(performFn('t', 1) == 6); 5888 fn performFn(start_value: i32) i32 { 5889 var result: i32 = start_value; 5890 result = two(result); 5891 result = three(result); 5892 return result; 5893 } 5894 {#code_end#} 5895 {#code_begin|syntax#} 5896 // From the line: 5897 // expect(performFn('o', 0) == 1); 5898 fn performFn(start_value: i32) i32 { 5899 var result: i32 = start_value; 5900 result = one(result); 5901 return result; 5902 } 5903 {#code_end#} 5904 {#code_begin|syntax#} 5905 // From the line: 5906 // expect(performFn('w', 99) == 99); 5907 fn performFn(start_value: i32) i32 { 5908 var result: i32 = start_value; 5909 return result; 5910 } 5911 {#code_end#} 5912 <p> 5913 Note that this happens even in a debug build; in a release build these generated functions still 5914 pass through rigorous LLVM optimizations. The important thing to note, however, is not that this 5915 is a way to write more optimized code, but that it is a way to make sure that what <em>should</em> happen 5916 at compile-time, <em>does</em> happen at compile-time. This catches more errors and as demonstrated 5917 later in this article, allows expressiveness that in other languages requires using macros, 5918 generated code, or a preprocessor to accomplish. 5919 </p> 5920 {#header_close#} 5921 {#header_open|Compile-Time Expressions#} 5922 <p> 5923 In Zig, it matters whether a given expression is known at compile-time or run-time. A programmer can 5924 use a {#syntax#}comptime{#endsyntax#} expression to guarantee that the expression will be evaluated at compile-time. 5925 If this cannot be accomplished, the compiler will emit an error. For example: 5926 </p> 5927 {#code_begin|test_err|unable to evaluate constant expression#} 5928 extern fn exit() noreturn; 5929 5930 test "foo" { 5931 comptime { 5932 exit(); 5933 } 5934 } 5935 {#code_end#} 5936 <p> 5937 It doesn't make sense that a program could call {#syntax#}exit(){#endsyntax#} (or any other external function) 5938 at compile-time, so this is a compile error. However, a {#syntax#}comptime{#endsyntax#} expression does much 5939 more than sometimes cause a compile error. 5940 </p> 5941 <p> 5942 Within a {#syntax#}comptime{#endsyntax#} expression: 5943 </p> 5944 <ul> 5945 <li>All variables are {#syntax#}comptime{#endsyntax#} variables.</li> 5946 <li>All {#syntax#}if{#endsyntax#}, {#syntax#}while{#endsyntax#}, {#syntax#}for{#endsyntax#}, and {#syntax#}switch{#endsyntax#} 5947 expressions are evaluated at compile-time, or emit a compile error if this is not possible.</li> 5948 <li>All function calls cause the compiler to interpret the function at compile-time, emitting a 5949 compile error if the function tries to do something that has global run-time side effects.</li> 5950 </ul> 5951 <p> 5952 This means that a programmer can create a function which is called both at compile-time and run-time, with 5953 no modification to the function required. 5954 </p> 5955 <p> 5956 Let's look at an example: 5957 </p> 5958 {#code_begin|test#} 5959 const expect = @import("std").testing.expect; 5960 5961 fn fibonacci(index: u32) u32 { 5962 if (index < 2) return index; 5963 return fibonacci(index - 1) + fibonacci(index - 2); 5964 } 5965 5966 test "fibonacci" { 5967 // test fibonacci at run-time 5968 try expect(fibonacci(7) == 13); 5969 5970 // test fibonacci at compile-time 5971 comptime { 5972 try expect(fibonacci(7) == 13); 5973 } 5974 } 5975 {#code_end#} 5976 <p> 5977 Imagine if we had forgotten the base case of the recursive function and tried to run the tests: 5978 </p> 5979 {#code_begin|test_err|operation caused overflow#} 5980 const expect = @import("std").testing.expect; 5981 5982 fn fibonacci(index: u32) u32 { 5983 //if (index < 2) return index; 5984 return fibonacci(index - 1) + fibonacci(index - 2); 5985 } 5986 5987 test "fibonacci" { 5988 comptime { 5989 try expect(fibonacci(7) == 13); 5990 } 5991 } 5992 {#code_end#} 5993 <p> 5994 The compiler produces an error which is a stack trace from trying to evaluate the 5995 function at compile-time. 5996 </p> 5997 <p> 5998 Luckily, we used an unsigned integer, and so when we tried to subtract 1 from 0, it triggered 5999 undefined behavior, which is always a compile error if the compiler knows it happened. 6000 But what would have happened if we used a signed integer? 6001 </p> 6002 {#code_begin|test_err|evaluation exceeded 1000 backwards branches#} 6003 const expect = @import("std").testing.expect; 6004 6005 fn fibonacci(index: i32) i32 { 6006 //if (index < 2) return index; 6007 return fibonacci(index - 1) + fibonacci(index - 2); 6008 } 6009 6010 test "fibonacci" { 6011 comptime { 6012 try expect(fibonacci(7) == 13); 6013 } 6014 } 6015 {#code_end#} 6016 <p> 6017 The compiler noticed that evaluating this function at compile-time took a long time, 6018 and thus emitted a compile error and gave up. If the programmer wants to increase 6019 the budget for compile-time computation, they can use a built-in function called 6020 {#link|@setEvalBranchQuota#} to change the default number 1000 to something else. 6021 </p> 6022 <p> 6023 What if we fix the base case, but put the wrong value in the {#syntax#}expect{#endsyntax#} line? 6024 </p> 6025 {#code_begin|test_err|test "fibonacci"... FAIL (TestUnexpectedResult)#} 6026 const expect = @import("std").testing.expect; 6027 6028 fn fibonacci(index: i32) i32 { 6029 if (index < 2) return index; 6030 return fibonacci(index - 1) + fibonacci(index - 2); 6031 } 6032 6033 test "fibonacci" { 6034 comptime { 6035 try expect(fibonacci(7) == 99999); 6036 } 6037 } 6038 {#code_end#} 6039 <p> 6040 What happened is Zig started interpreting the {#syntax#}expect{#endsyntax#} function with the 6041 parameter {#syntax#}ok{#endsyntax#} set to {#syntax#}false{#endsyntax#}. When the interpreter hit 6042 {#syntax#}@panic{#endsyntax#} it emitted a compile error because a panic during compile 6043 causes a compile error if it is detected at compile-time. 6044 </p> 6045 6046 <p> 6047 In the global scope (outside of any function), all expressions are implicitly 6048 {#syntax#}comptime{#endsyntax#} expressions. This means that we can use functions to 6049 initialize complex static data. For example: 6050 </p> 6051 {#code_begin|test#} 6052 const first_25_primes = firstNPrimes(25); 6053 const sum_of_first_25_primes = sum(&first_25_primes); 6054 6055 fn firstNPrimes(comptime n: usize) [n]i32 { 6056 var prime_list: [n]i32 = undefined; 6057 var next_index: usize = 0; 6058 var test_number: i32 = 2; 6059 while (next_index < prime_list.len) : (test_number += 1) { 6060 var test_prime_index: usize = 0; 6061 var is_prime = true; 6062 while (test_prime_index < next_index) : (test_prime_index += 1) { 6063 if (test_number % prime_list[test_prime_index] == 0) { 6064 is_prime = false; 6065 break; 6066 } 6067 } 6068 if (is_prime) { 6069 prime_list[next_index] = test_number; 6070 next_index += 1; 6071 } 6072 } 6073 return prime_list; 6074 } 6075 6076 fn sum(numbers: []const i32) i32 { 6077 var result: i32 = 0; 6078 for (numbers) |x| { 6079 result += x; 6080 } 6081 return result; 6082 } 6083 6084 test "variable values" { 6085 try @import("std").testing.expect(sum_of_first_25_primes == 1060); 6086 } 6087 {#code_end#} 6088 <p> 6089 When we compile this program, Zig generates the constants 6090 with the answer pre-computed. Here are the lines from the generated LLVM IR: 6091 </p> 6092 <pre><code class="llvm">@0 = internal unnamed_addr constant [25 x i32] [i32 2, i32 3, i32 5, i32 7, i32 11, i32 13, i32 17, i32 19, i32 23, i32 29, i32 31, i32 37, i32 41, i32 43, i32 47, i32 53, i32 59, i32 61, i32 67, i32 71, i32 73, i32 79, i32 83, i32 89, i32 97] 6093 @1 = internal unnamed_addr constant i32 1060</code></pre> 6094 <p> 6095 Note that we did not have to do anything special with the syntax of these functions. For example, 6096 we could call the {#syntax#}sum{#endsyntax#} function as is with a slice of numbers whose length and values were 6097 only known at run-time. 6098 </p> 6099 {#header_close#} 6100 {#header_close#} 6101 {#header_open|Generic Data Structures#} 6102 <p> 6103 Zig uses these capabilities to implement generic data structures without introducing any 6104 special-case syntax. If you followed along so far, you may already know how to create a 6105 generic data structure. 6106 </p> 6107 <p> 6108 Here is an example of a generic {#syntax#}List{#endsyntax#} data structure, that we will instantiate with 6109 the type {#syntax#}i32{#endsyntax#}. In Zig we refer to the type as {#syntax#}List(i32){#endsyntax#}. 6110 </p> 6111 {#code_begin|syntax#} 6112 fn List(comptime T: type) type { 6113 return struct { 6114 items: []T, 6115 len: usize, 6116 }; 6117 } 6118 {#code_end#} 6119 <p> 6120 That's it. It's a function that returns an anonymous {#syntax#}struct{#endsyntax#}. For the purposes of error messages 6121 and debugging, Zig infers the name {#syntax#}"List(i32)"{#endsyntax#} from the function name and parameters invoked when creating 6122 the anonymous struct. 6123 </p> 6124 <p> 6125 To keep the language small and uniform, all aggregate types in Zig are anonymous. To give a type 6126 a name, we assign it to a constant: 6127 </p> 6128 {#code_begin|syntax#} 6129 const Node = struct { 6130 next: *Node, 6131 name: []u8, 6132 }; 6133 {#code_end#} 6134 <p> 6135 This works because all top level declarations are order-independent, and as long as there isn't 6136 an actual infinite regression, values can refer to themselves, directly or indirectly. In this case, 6137 {#syntax#}Node{#endsyntax#} refers to itself as a pointer, which is not actually an infinite regression, so 6138 it works fine. 6139 </p> 6140 {#header_close#} 6141 {#header_open|Case Study: printf in Zig#} 6142 <p> 6143 Putting all of this together, let's see how {#syntax#}printf{#endsyntax#} works in Zig. 6144 </p> 6145 {#code_begin|exe|printf#} 6146 const print = @import("std").debug.print; 6147 6148 const a_number: i32 = 1234; 6149 const a_string = "foobar"; 6150 6151 pub fn main() void { 6152 print("here is a string: '{s}' here is a number: {}\n", .{a_string, a_number}); 6153 } 6154 {#code_end#} 6155 6156 <p> 6157 Let's crack open the implementation of this and see how it works: 6158 </p> 6159 6160 {#code_begin|syntax#} 6161 /// Calls print and then flushes the buffer. 6162 pub fn printf(self: *Writer, comptime format: []const u8, args: anytype) anyerror!void { 6163 const State = enum { 6164 start, 6165 open_brace, 6166 close_brace, 6167 }; 6168 6169 comptime var start_index: usize = 0; 6170 comptime var state = State.start; 6171 comptime var next_arg: usize = 0; 6172 6173 inline for (format) |c, i| { 6174 switch (state) { 6175 State.start => switch (c) { 6176 '{' => { 6177 if (start_index < i) try self.write(format[start_index..i]); 6178 state = State.open_brace; 6179 }, 6180 '}' => { 6181 if (start_index < i) try self.write(format[start_index..i]); 6182 state = State.close_brace; 6183 }, 6184 else => {}, 6185 }, 6186 State.open_brace => switch (c) { 6187 '{' => { 6188 state = State.start; 6189 start_index = i; 6190 }, 6191 '}' => { 6192 try self.printValue(args[next_arg]); 6193 next_arg += 1; 6194 state = State.start; 6195 start_index = i + 1; 6196 }, 6197 else => @compileError("Unknown format character: " ++ c), 6198 }, 6199 State.close_brace => switch (c) { 6200 '}' => { 6201 state = State.start; 6202 start_index = i; 6203 }, 6204 else => @compileError("Single '}' encountered in format string"), 6205 }, 6206 } 6207 } 6208 comptime { 6209 if (args.len != next_arg) { 6210 @compileError("Unused arguments"); 6211 } 6212 if (state != State.Start) { 6213 @compileError("Incomplete format string: " ++ format); 6214 } 6215 } 6216 if (start_index < format.len) { 6217 try self.write(format[start_index..format.len]); 6218 } 6219 try self.flush(); 6220 } 6221 {#code_end#} 6222 <p> 6223 This is a proof of concept implementation; the actual function in the standard library has more 6224 formatting capabilities. 6225 </p> 6226 <p> 6227 Note that this is not hard-coded into the Zig compiler; this is userland code in the standard library. 6228 </p> 6229 <p> 6230 When this function is analyzed from our example code above, Zig partially evaluates the function 6231 and emits a function that actually looks like this: 6232 </p> 6233 {#code_begin|syntax#} 6234 pub fn printf(self: *Writer, arg0: i32, arg1: []const u8) !void { 6235 try self.write("here is a string: '"); 6236 try self.printValue(arg0); 6237 try self.write("' here is a number: "); 6238 try self.printValue(arg1); 6239 try self.write("\n"); 6240 try self.flush(); 6241 } 6242 {#code_end#} 6243 <p> 6244 {#syntax#}printValue{#endsyntax#} is a function that takes a parameter of any type, and does different things depending 6245 on the type: 6246 </p> 6247 {#code_begin|syntax#} 6248 pub fn printValue(self: *Writer, value: anytype) !void { 6249 switch (@typeInfo(@TypeOf(value))) { 6250 .Int => { 6251 return self.printInt(T, value); 6252 }, 6253 .Float => { 6254 return self.printFloat(T, value); 6255 }, 6256 else => { 6257 @compileError("Unable to print type '" ++ @typeName(T) ++ "'"); 6258 }, 6259 } 6260 } 6261 {#code_end#} 6262 <p> 6263 And now, what happens if we give too many arguments to {#syntax#}printf{#endsyntax#}? 6264 </p> 6265 {#code_begin|test_err|Unused argument in "here is a string: '{s}' here is a number: {}#} 6266 const print = @import("std").debug.print; 6267 6268 const a_number: i32 = 1234; 6269 const a_string = "foobar"; 6270 6271 test "printf too many arguments" { 6272 print("here is a string: '{s}' here is a number: {}\n", .{ 6273 a_string, 6274 a_number, 6275 a_number, 6276 }); 6277 } 6278 {#code_end#} 6279 <p> 6280 Zig gives programmers the tools needed to protect themselves against their own mistakes. 6281 </p> 6282 <p> 6283 Zig doesn't care whether the format argument is a string literal, 6284 only that it is a compile-time known value that can be coerced to a {#syntax#}[]const u8{#endsyntax#}: 6285 </p> 6286 {#code_begin|exe|printf#} 6287 const print = @import("std").debug.print; 6288 6289 const a_number: i32 = 1234; 6290 const a_string = "foobar"; 6291 const fmt = "here is a string: '{s}' here is a number: {}\n"; 6292 6293 pub fn main() void { 6294 print(fmt, .{a_string, a_number}); 6295 } 6296 {#code_end#} 6297 <p> 6298 This works fine. 6299 </p> 6300 <p> 6301 Zig does not special case string formatting in the compiler and instead exposes enough power to accomplish this 6302 task in userland. It does so without introducing another language on top of Zig, such as 6303 a macro language or a preprocessor language. It's Zig all the way down. 6304 </p> 6305 {#header_close#} 6306 {#see_also|inline while|inline for#} 6307 {#header_close#} 6308 {#header_open|Assembly#} 6309 <p> 6310 For some use cases, it may be necessary to directly control the machine code generated 6311 by Zig programs, rather than relying on Zig's code generation. For these cases, one 6312 can use inline assembly. Here is an example of implementing Hello, World on x86_64 Linux 6313 using inline assembly: 6314 </p> 6315 {#code_begin|exe#} 6316 {#target_linux_x86_64#} 6317 pub fn main() noreturn { 6318 const msg = "hello world\n"; 6319 _ = syscall3(SYS_write, STDOUT_FILENO, @ptrToInt(msg), msg.len); 6320 _ = syscall1(SYS_exit, 0); 6321 unreachable; 6322 } 6323 6324 pub const SYS_write = 1; 6325 pub const SYS_exit = 60; 6326 6327 pub const STDOUT_FILENO = 1; 6328 6329 pub fn syscall1(number: usize, arg1: usize) usize { 6330 return asm volatile ("syscall" 6331 : [ret] "={rax}" (-> usize) 6332 : [number] "{rax}" (number), 6333 [arg1] "{rdi}" (arg1) 6334 : "rcx", "r11" 6335 ); 6336 } 6337 6338 pub fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usize { 6339 return asm volatile ("syscall" 6340 : [ret] "={rax}" (-> usize) 6341 : [number] "{rax}" (number), 6342 [arg1] "{rdi}" (arg1), 6343 [arg2] "{rsi}" (arg2), 6344 [arg3] "{rdx}" (arg3) 6345 : "rcx", "r11" 6346 ); 6347 } 6348 {#code_end#} 6349 <p> 6350 Dissecting the syntax: 6351 </p> 6352 <pre>{#syntax#}// Inline assembly is an expression which returns a value. 6353 // the `asm` keyword begins the expression. 6354 _ = asm 6355 // `volatile` is an optional modifier that tells Zig this 6356 // inline assembly expression has side-effects. Without 6357 // `volatile`, Zig is allowed to delete the inline assembly 6358 // code if the result is unused. 6359 volatile ( 6360 // Next is a comptime string which is the assembly code. 6361 // Inside this string one may use `%[ret]`, `%[number]`, 6362 // or `%[arg1]` where a register is expected, to specify 6363 // the register that Zig uses for the argument or return value, 6364 // if the register constraint strings are used. However in 6365 // the below code, this is not used. A literal `%` can be 6366 // obtained by escaping it with a double percent: `%%`. 6367 // Often multiline string syntax comes in handy here. 6368 \\syscall 6369 // Next is the output. It is possible in the future Zig will 6370 // support multiple outputs, depending on how 6371 // https://github.com/ziglang/zig/issues/215 is resolved. 6372 // It is allowed for there to be no outputs, in which case 6373 // this colon would be directly followed by the colon for the inputs. 6374 : 6375 // This specifies the name to be used in `%[ret]` syntax in 6376 // the above assembly string. This example does not use it, 6377 // but the syntax is mandatory. 6378 [ret] 6379 // Next is the output constraint string. This feature is still 6380 // considered unstable in Zig, and so LLVM/GCC documentation 6381 // must be used to understand the semantics. 6382 // http://releases.llvm.org/10.0.0/docs/LangRef.html#inline-asm-constraint-string 6383 // https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html 6384 // In this example, the constraint string means "the result value of 6385 // this inline assembly instruction is whatever is in $rax". 6386 "={rax}" 6387 // Next is either a value binding, or `->` and then a type. The 6388 // type is the result type of the inline assembly expression. 6389 // If it is a value binding, then `%[ret]` syntax would be used 6390 // to refer to the register bound to the value. 6391 (-> usize) 6392 // Next is the list of inputs. 6393 // The constraint for these inputs means, "when the assembly code is 6394 // executed, $rax shall have the value of `number` and $rdi shall have 6395 // the value of `arg1`". Any number of input parameters is allowed, 6396 // including none. 6397 : [number] "{rax}" (number), 6398 [arg1] "{rdi}" (arg1) 6399 // Next is the list of clobbers. These declare a set of registers whose 6400 // values will not be preserved by the execution of this assembly code. 6401 // These do not include output or input registers. The special clobber 6402 // value of "memory" means that the assembly writes to arbitrary undeclared 6403 // memory locations - not only the memory pointed to by a declared indirect 6404 // output. In this example we list $rcx and $r11 because it is known the 6405 // kernel syscall does not preserve these registers. 6406 : "rcx", "r11" 6407 );{#endsyntax#}</pre> 6408 <p> 6409 For i386 and x86_64 targets, the syntax is AT&T syntax, rather than the more 6410 popular Intel syntax. This is due to technical constraints; assembly parsing is 6411 provided by LLVM and its support for Intel syntax is buggy and not well tested. 6412 </p> 6413 <p> 6414 Some day Zig may have its own assembler. This would allow it to integrate more seamlessly 6415 into the language, as well as be compatible with the popular NASM syntax. This documentation 6416 section will be updated before 1.0.0 is released, with a conclusive statement about the status 6417 of AT&T vs Intel/NASM syntax. 6418 </p> 6419 {#header_open|Output Constraints#} 6420 <p> 6421 Output constraints are still considered to be unstable in Zig, and 6422 so 6423 <a href="http://releases.llvm.org/10.0.0/docs/LangRef.html#inline-asm-constraint-string">LLVM documentation</a> 6424 and 6425 <a href="https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html">GCC documentation</a> 6426 must be used to understand the semantics. 6427 </p> 6428 <p> 6429 Note that some breaking changes to output constraints are planned with 6430 <a href="https://github.com/ziglang/zig/issues/215">issue #215</a>. 6431 </p> 6432 {#header_close#} 6433 6434 {#header_open|Input Constraints#} 6435 <p> 6436 Input constraints are still considered to be unstable in Zig, and 6437 so 6438 <a href="http://releases.llvm.org/10.0.0/docs/LangRef.html#inline-asm-constraint-string">LLVM documentation</a> 6439 and 6440 <a href="https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html">GCC documentation</a> 6441 must be used to understand the semantics. 6442 </p> 6443 <p> 6444 Note that some breaking changes to input constraints are planned with 6445 <a href="https://github.com/ziglang/zig/issues/215">issue #215</a>. 6446 </p> 6447 {#header_close#} 6448 6449 {#header_open|Clobbers#} 6450 <p> 6451 Clobbers are the set of registers whose values will not be preserved by the execution of 6452 the assembly code. These do not include output or input registers. The special clobber 6453 value of {#syntax#}"memory"{#endsyntax#} means that the assembly causes writes to 6454 arbitrary undeclared memory locations - not only the memory pointed to by a declared 6455 indirect output. 6456 </p> 6457 <p> 6458 Failure to declare the full set of clobbers for a given inline assembly 6459 expression is unchecked {#link|Undefined Behavior#}. 6460 </p> 6461 {#header_close#} 6462 6463 {#header_open|Global Assembly#} 6464 <p> 6465 When an assembly expression occurs in a top level {#link|comptime#} block, this is 6466 <strong>global assembly</strong>. 6467 </p> 6468 <p> 6469 This kind of assembly has different rules than inline assembly. First, {#syntax#}volatile{#endsyntax#} 6470 is not valid because all global assembly is unconditionally included. 6471 Second, there are no inputs, outputs, or clobbers. All global assembly is concatenated 6472 verbatim into one long string and assembled together. There are no template substitution rules regarding 6473 <code>%</code> as there are in inline assembly expressions. 6474 </p> 6475 {#code_begin|test|global-asm#} 6476 {#target_linux_x86_64#} 6477 const std = @import("std"); 6478 const expect = std.testing.expect; 6479 6480 comptime { 6481 asm ( 6482 \\.global my_func; 6483 \\.type my_func, @function; 6484 \\my_func: 6485 \\ lea (%rdi,%rsi,1),%eax 6486 \\ retq 6487 ); 6488 } 6489 6490 extern fn my_func(a: i32, b: i32) i32; 6491 6492 test "global assembly" { 6493 try expect(my_func(12, 34) == 46); 6494 } 6495 {#code_end#} 6496 {#header_close#} 6497 {#header_close#} 6498 6499 {#header_open|Atomics#} 6500 <p>TODO: @fence()</p> 6501 <p>TODO: @atomic rmw</p> 6502 <p>TODO: builtin atomic memory ordering enum</p> 6503 {#header_close#} 6504 {#header_open|Async Functions#} 6505 <p> 6506 When a function is called, a frame is pushed to the stack, 6507 the function runs until it reaches a return statement, and then the frame is popped from the stack. 6508 At the callsite, the following code does not run until the function returns. 6509 </p> 6510 <p> 6511 An async function is a function whose callsite is split into an {#syntax#}async{#endsyntax#} initiation, 6512 followed by an {#syntax#}await{#endsyntax#} completion. Its frame is 6513 provided explicitly by the caller, and it can be suspended and resumed any number of times. 6514 </p> 6515 <p> 6516 Zig infers that a function is {#syntax#}async{#endsyntax#} when it observes that the function contains 6517 a <strong>suspension point</strong>. Async functions can be called the same as normal functions. A 6518 function call of an async function is a suspend point. 6519 </p> 6520 {#header_open|Suspend and Resume#} 6521 <p> 6522 At any point, a function may suspend itself. This causes control flow to 6523 return to the callsite (in the case of the first suspension), 6524 or resumer (in the case of subsequent suspensions). 6525 </p> 6526 {#code_begin|test#} 6527 const std = @import("std"); 6528 const expect = std.testing.expect; 6529 6530 var x: i32 = 1; 6531 6532 test "suspend with no resume" { 6533 var frame = async func(); 6534 try expect(x == 2); 6535 } 6536 6537 fn func() void { 6538 x += 1; 6539 suspend {} 6540 // This line is never reached because the suspend has no matching resume. 6541 x += 1; 6542 } 6543 {#code_end#} 6544 <p> 6545 In the same way that each allocation should have a corresponding free, 6546 Each {#syntax#}suspend{#endsyntax#} should have a corresponding {#syntax#}resume{#endsyntax#}. 6547 A <strong>suspend block</strong> allows a function to put a pointer to its own 6548 frame somewhere, for example into an event loop, even if that action will perform a 6549 {#syntax#}resume{#endsyntax#} operation on a different thread. 6550 {#link|@frame#} provides access to the async function frame pointer. 6551 </p> 6552 {#code_begin|test#} 6553 const std = @import("std"); 6554 const expect = std.testing.expect; 6555 6556 var the_frame: anyframe = undefined; 6557 var result = false; 6558 6559 test "async function suspend with block" { 6560 _ = async testSuspendBlock(); 6561 try expect(!result); 6562 resume the_frame; 6563 try expect(result); 6564 } 6565 6566 fn testSuspendBlock() void { 6567 suspend { 6568 comptime try expect(@TypeOf(@frame()) == *@Frame(testSuspendBlock)); 6569 the_frame = @frame(); 6570 } 6571 result = true; 6572 } 6573 {#code_end#} 6574 <p> 6575 {#syntax#}suspend{#endsyntax#} causes a function to be {#syntax#}async{#endsyntax#}. 6576 </p> 6577 6578 {#header_open|Resuming from Suspend Blocks#} 6579 <p> 6580 Upon entering a {#syntax#}suspend{#endsyntax#} block, the async function is already considered 6581 suspended, and can be resumed. For example, if you started another kernel thread, 6582 and had that thread call {#syntax#}resume{#endsyntax#} on the frame pointer provided by the 6583 {#link|@frame#}, the new thread would begin executing after the suspend 6584 block, while the old thread continued executing the suspend block. 6585 </p> 6586 <p> 6587 However, the async function can be directly resumed from the suspend block, in which case it 6588 never returns to its resumer and continues executing. 6589 </p> 6590 {#code_begin|test#} 6591 const std = @import("std"); 6592 const expect = std.testing.expect; 6593 6594 test "resume from suspend" { 6595 var my_result: i32 = 1; 6596 _ = async testResumeFromSuspend(&my_result); 6597 try std.testing.expect(my_result == 2); 6598 } 6599 fn testResumeFromSuspend(my_result: *i32) void { 6600 suspend { 6601 resume @frame(); 6602 } 6603 my_result.* += 1; 6604 suspend {} 6605 my_result.* += 1; 6606 } 6607 {#code_end#} 6608 <p> 6609 This is guaranteed to tail call, and therefore will not cause a new stack frame. 6610 </p> 6611 {#header_close#} 6612 {#header_close#} 6613 6614 {#header_open|Async and Await#} 6615 <p> 6616 In the same way that every {#syntax#}suspend{#endsyntax#} has a matching 6617 {#syntax#}resume{#endsyntax#}, every {#syntax#}async{#endsyntax#} has a matching {#syntax#}await{#endsyntax#}. 6618 </p> 6619 {#code_begin|test#} 6620 const std = @import("std"); 6621 const expect = std.testing.expect; 6622 6623 test "async and await" { 6624 // The test block is not async and so cannot have a suspend 6625 // point in it. By using the nosuspend keyword, we promise that 6626 // the code in amain will finish executing without suspending 6627 // back to the test block. 6628 nosuspend amain(); 6629 } 6630 6631 fn amain() void { 6632 var frame = async func(); 6633 comptime try expect(@TypeOf(frame) == @Frame(func)); 6634 6635 const ptr: anyframe->void = &frame; 6636 const any_ptr: anyframe = ptr; 6637 6638 resume any_ptr; 6639 await ptr; 6640 } 6641 6642 fn func() void { 6643 suspend {} 6644 } 6645 {#code_end#} 6646 <p> 6647 The {#syntax#}await{#endsyntax#} keyword is used to coordinate with an async function's 6648 {#syntax#}return{#endsyntax#} statement. 6649 </p> 6650 <p> 6651 {#syntax#}await{#endsyntax#} is a suspend point, and takes as an operand anything that 6652 coerces to {#syntax#}anyframe->T{#endsyntax#}. 6653 </p> 6654 <p> 6655 There is a common misconception that {#syntax#}await{#endsyntax#} resumes the target function. 6656 It is the other way around: it suspends until the target function completes. 6657 In the event that the target function has already completed, {#syntax#}await{#endsyntax#} 6658 does not suspend; instead it copies the 6659 return value directly from the target function's frame. 6660 </p> 6661 {#code_begin|test#} 6662 const std = @import("std"); 6663 const expect = std.testing.expect; 6664 6665 var the_frame: anyframe = undefined; 6666 var final_result: i32 = 0; 6667 6668 test "async function await" { 6669 seq('a'); 6670 _ = async amain(); 6671 seq('f'); 6672 resume the_frame; 6673 seq('i'); 6674 try expect(final_result == 1234); 6675 try expect(std.mem.eql(u8, &seq_points, "abcdefghi")); 6676 } 6677 fn amain() void { 6678 seq('b'); 6679 var f = async another(); 6680 seq('e'); 6681 final_result = await f; 6682 seq('h'); 6683 } 6684 fn another() i32 { 6685 seq('c'); 6686 suspend { 6687 seq('d'); 6688 the_frame = @frame(); 6689 } 6690 seq('g'); 6691 return 1234; 6692 } 6693 6694 var seq_points = [_]u8{0} ** "abcdefghi".len; 6695 var seq_index: usize = 0; 6696 6697 fn seq(c: u8) void { 6698 seq_points[seq_index] = c; 6699 seq_index += 1; 6700 } 6701 {#code_end#} 6702 <p> 6703 In general, {#syntax#}suspend{#endsyntax#} is lower level than {#syntax#}await{#endsyntax#}. Most application 6704 code will use only {#syntax#}async{#endsyntax#} and {#syntax#}await{#endsyntax#}, but event loop 6705 implementations will make use of {#syntax#}suspend{#endsyntax#} internally. 6706 </p> 6707 {#header_close#} 6708 6709 {#header_open|Async Function Example#} 6710 <p> 6711 Putting all of this together, here is an example of typical 6712 {#syntax#}async{#endsyntax#}/{#syntax#}await{#endsyntax#} usage: 6713 </p> 6714 {#code_begin|exe|async#} 6715 const std = @import("std"); 6716 const Allocator = std.mem.Allocator; 6717 6718 pub fn main() void { 6719 _ = async amainWrap(); 6720 6721 // Typically we would use an event loop to manage resuming async functions, 6722 // but in this example we hard code what the event loop would do, 6723 // to make things deterministic. 6724 resume global_file_frame; 6725 resume global_download_frame; 6726 } 6727 6728 fn amainWrap() void { 6729 amain() catch |e| { 6730 std.debug.print("{}\n", .{e}); 6731 if (@errorReturnTrace()) |trace| { 6732 std.debug.dumpStackTrace(trace.*); 6733 } 6734 std.process.exit(1); 6735 }; 6736 } 6737 6738 fn amain() !void { 6739 const allocator = std.heap.page_allocator; 6740 var download_frame = async fetchUrl(allocator, "https://example.com/"); 6741 var awaited_download_frame = false; 6742 errdefer if (!awaited_download_frame) { 6743 if (await download_frame) |r| allocator.free(r) else |_| {} 6744 }; 6745 6746 var file_frame = async readFile(allocator, "something.txt"); 6747 var awaited_file_frame = false; 6748 errdefer if (!awaited_file_frame) { 6749 if (await file_frame) |r| allocator.free(r) else |_| {} 6750 }; 6751 6752 awaited_file_frame = true; 6753 const file_text = try await file_frame; 6754 defer allocator.free(file_text); 6755 6756 awaited_download_frame = true; 6757 const download_text = try await download_frame; 6758 defer allocator.free(download_text); 6759 6760 std.debug.print("download_text: {s}\n", .{download_text}); 6761 std.debug.print("file_text: {s}\n", .{file_text}); 6762 } 6763 6764 var global_download_frame: anyframe = undefined; 6765 fn fetchUrl(allocator: *Allocator, url: []const u8) ![]u8 { 6766 const result = try std.mem.dupe(allocator, u8, "this is the downloaded url contents"); 6767 errdefer allocator.free(result); 6768 suspend { 6769 global_download_frame = @frame(); 6770 } 6771 std.debug.print("fetchUrl returning\n", .{}); 6772 return result; 6773 } 6774 6775 var global_file_frame: anyframe = undefined; 6776 fn readFile(allocator: *Allocator, filename: []const u8) ![]u8 { 6777 const result = try std.mem.dupe(allocator, u8, "this is the file contents"); 6778 errdefer allocator.free(result); 6779 suspend { 6780 global_file_frame = @frame(); 6781 } 6782 std.debug.print("readFile returning\n", .{}); 6783 return result; 6784 } 6785 {#code_end#} 6786 <p> 6787 Now we remove the {#syntax#}suspend{#endsyntax#} and {#syntax#}resume{#endsyntax#} code, and 6788 observe the same behavior, with one tiny difference: 6789 </p> 6790 {#code_begin|exe|blocking#} 6791 const std = @import("std"); 6792 const Allocator = std.mem.Allocator; 6793 6794 pub fn main() void { 6795 _ = async amainWrap(); 6796 } 6797 6798 fn amainWrap() void { 6799 amain() catch |e| { 6800 std.debug.print("{}\n", .{e}); 6801 if (@errorReturnTrace()) |trace| { 6802 std.debug.dumpStackTrace(trace.*); 6803 } 6804 std.process.exit(1); 6805 }; 6806 } 6807 6808 fn amain() !void { 6809 const allocator = std.heap.page_allocator; 6810 var download_frame = async fetchUrl(allocator, "https://example.com/"); 6811 var awaited_download_frame = false; 6812 errdefer if (!awaited_download_frame) { 6813 if (await download_frame) |r| allocator.free(r) else |_| {} 6814 }; 6815 6816 var file_frame = async readFile(allocator, "something.txt"); 6817 var awaited_file_frame = false; 6818 errdefer if (!awaited_file_frame) { 6819 if (await file_frame) |r| allocator.free(r) else |_| {} 6820 }; 6821 6822 awaited_file_frame = true; 6823 const file_text = try await file_frame; 6824 defer allocator.free(file_text); 6825 6826 awaited_download_frame = true; 6827 const download_text = try await download_frame; 6828 defer allocator.free(download_text); 6829 6830 std.debug.print("download_text: {s}\n", .{download_text}); 6831 std.debug.print("file_text: {s}\n", .{file_text}); 6832 } 6833 6834 fn fetchUrl(allocator: *Allocator, url: []const u8) ![]u8 { 6835 const result = try std.mem.dupe(allocator, u8, "this is the downloaded url contents"); 6836 errdefer allocator.free(result); 6837 std.debug.print("fetchUrl returning\n", .{}); 6838 return result; 6839 } 6840 6841 fn readFile(allocator: *Allocator, filename: []const u8) ![]u8 { 6842 const result = try std.mem.dupe(allocator, u8, "this is the file contents"); 6843 errdefer allocator.free(result); 6844 std.debug.print("readFile returning\n", .{}); 6845 return result; 6846 } 6847 {#code_end#} 6848 <p> 6849 Previously, the {#syntax#}fetchUrl{#endsyntax#} and {#syntax#}readFile{#endsyntax#} functions suspended, 6850 and were resumed in an order determined by the {#syntax#}main{#endsyntax#} function. Now, 6851 since there are no suspend points, the order of the printed "... returning" messages 6852 is determined by the order of {#syntax#}async{#endsyntax#} callsites. 6853 </p> 6854 {#header_close#} 6855 6856 {#header_close#} 6857 {#header_open|Builtin Functions|2col#} 6858 <p> 6859 Builtin functions are provided by the compiler and are prefixed with <code>@</code>. 6860 The {#syntax#}comptime{#endsyntax#} keyword on a parameter means that the parameter must be known 6861 at compile time. 6862 </p> 6863 {#header_open|@addWithOverflow#} 6864 <pre>{#syntax#}@addWithOverflow(comptime T: type, a: T, b: T, result: *T) bool{#endsyntax#}</pre> 6865 <p> 6866 Performs {#syntax#}result.* = a + b{#endsyntax#}. If overflow or underflow occurs, 6867 stores the overflowed bits in {#syntax#}result{#endsyntax#} and returns {#syntax#}true{#endsyntax#}. 6868 If no overflow or underflow occurs, returns {#syntax#}false{#endsyntax#}. 6869 </p> 6870 {#header_close#} 6871 {#header_open|@alignCast#} 6872 <pre>{#syntax#}@alignCast(comptime alignment: u29, ptr: anytype) anytype{#endsyntax#}</pre> 6873 <p> 6874 {#syntax#}ptr{#endsyntax#} can be {#syntax#}*T{#endsyntax#}, {#syntax#}fn(){#endsyntax#}, {#syntax#}?*T{#endsyntax#}, 6875 {#syntax#}?fn(){#endsyntax#}, or {#syntax#}[]T{#endsyntax#}. It returns the same type as {#syntax#}ptr{#endsyntax#} 6876 except with the alignment adjusted to the new value. 6877 </p> 6878 <p>A {#link|pointer alignment safety check|Incorrect Pointer Alignment#} is added 6879 to the generated code to make sure the pointer is aligned as promised.</p> 6880 6881 {#header_close#} 6882 {#header_open|@alignOf#} 6883 <pre>{#syntax#}@alignOf(comptime T: type) comptime_int{#endsyntax#}</pre> 6884 <p> 6885 This function returns the number of bytes that this type should be aligned to 6886 for the current target to match the C ABI. When the child type of a pointer has 6887 this alignment, the alignment can be omitted from the type. 6888 </p> 6889 <pre>{#syntax#}const expect = @import("std").debug.assert; 6890 comptime { 6891 assert(*u32 == *align(@alignOf(u32)) u32); 6892 }{#endsyntax#}</pre> 6893 <p> 6894 The result is a target-specific compile time constant. It is guaranteed to be 6895 less than or equal to {#link|@sizeOf(T)|@sizeOf#}. 6896 </p> 6897 {#see_also|Alignment#} 6898 {#header_close#} 6899 6900 {#header_open|@as#} 6901 <pre>{#syntax#}@as(comptime T: type, expression) T{#endsyntax#}</pre> 6902 <p> 6903 Performs {#link|Type Coercion#}. This cast is allowed when the conversion is unambiguous and safe, 6904 and is the preferred way to convert between types, whenever possible. 6905 </p> 6906 {#header_close#} 6907 6908 {#header_open|@asyncCall#} 6909 <pre>{#syntax#}@asyncCall(frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction))) u8, result_ptr, function_ptr, args: anytype) anyframe->T{#endsyntax#}</pre> 6910 <p> 6911 {#syntax#}@asyncCall{#endsyntax#} performs an {#syntax#}async{#endsyntax#} call on a function pointer, 6912 which may or may not be an {#link|async function|Async Functions#}. 6913 </p> 6914 <p> 6915 The provided {#syntax#}frame_buffer{#endsyntax#} must be large enough to fit the entire function frame. 6916 This size can be determined with {#link|@frameSize#}. To provide a too-small buffer 6917 invokes safety-checked {#link|Undefined Behavior#}. 6918 </p> 6919 <p> 6920 {#syntax#}result_ptr{#endsyntax#} is optional ({#link|null#} may be provided). If provided, 6921 the function call will write its result directly to the result pointer, which will be available to 6922 read after {#link|await|Async and Await#} completes. Any result location provided to 6923 {#syntax#}await{#endsyntax#} will copy the result from {#syntax#}result_ptr{#endsyntax#}. 6924 </p> 6925 {#code_begin|test#} 6926 const std = @import("std"); 6927 const expect = std.testing.expect; 6928 6929 test "async fn pointer in a struct field" { 6930 var data: i32 = 1; 6931 const Foo = struct { 6932 bar: fn (*i32) callconv(.Async) void, 6933 }; 6934 var foo = Foo{ .bar = func }; 6935 var bytes: [64]u8 align(@alignOf(@Frame(func))) = undefined; 6936 const f = @asyncCall(&bytes, {}, foo.bar, .{&data}); 6937 try expect(data == 2); 6938 resume f; 6939 try expect(data == 4); 6940 } 6941 6942 fn func(y: *i32) void { 6943 defer y.* += 2; 6944 y.* += 1; 6945 suspend {} 6946 } 6947 {#code_end#} 6948 {#header_close#} 6949 6950 {#header_open|@atomicLoad#} 6951 <pre>{#syntax#}@atomicLoad(comptime T: type, ptr: *const T, comptime ordering: builtin.AtomicOrder) T{#endsyntax#}</pre> 6952 <p> 6953 This builtin function atomically dereferences a pointer and returns the value. 6954 </p> 6955 <p> 6956 {#syntax#}T{#endsyntax#} must be a pointer, a {#syntax#}bool{#endsyntax#}, a float, 6957 an integer or an enum. 6958 </p> 6959 {#header_close#} 6960 {#header_open|@atomicRmw#} 6961 <pre>{#syntax#}@atomicRmw(comptime T: type, ptr: *T, comptime op: builtin.AtomicRmwOp, operand: T, comptime ordering: builtin.AtomicOrder) T{#endsyntax#}</pre> 6962 <p> 6963 This builtin function atomically modifies memory and then returns the previous value. 6964 </p> 6965 <p> 6966 {#syntax#}T{#endsyntax#} must be a pointer, a {#syntax#}bool{#endsyntax#}, a float, 6967 an integer or an enum. 6968 </p> 6969 <p> 6970 Supported operations: 6971 </p> 6972 <ul> 6973 <li>{#syntax#}.Xchg{#endsyntax#} - stores the operand unmodified. Supports enums, integers and floats.</li> 6974 <li>{#syntax#}.Add{#endsyntax#} - for integers, twos complement wraparound addition. 6975 Also supports {#link|Floats#}.</li> 6976 <li>{#syntax#}.Sub{#endsyntax#} - for integers, twos complement wraparound subtraction. 6977 Also supports {#link|Floats#}.</li> 6978 <li>{#syntax#}.And{#endsyntax#} - bitwise and</li> 6979 <li>{#syntax#}.Nand{#endsyntax#} - bitwise nand</li> 6980 <li>{#syntax#}.Or{#endsyntax#} - bitwise or</li> 6981 <li>{#syntax#}.Xor{#endsyntax#} - bitwise xor</li> 6982 <li>{#syntax#}.Max{#endsyntax#} - stores the operand if it is larger. Supports integers and floats.</li> 6983 <li>{#syntax#}.Min{#endsyntax#} - stores the operand if it is smaller. Supports integers and floats.</li> 6984 </ul> 6985 {#header_close#} 6986 {#header_open|@atomicStore#} 6987 <pre>{#syntax#}@atomicStore(comptime T: type, ptr: *T, value: T, comptime ordering: builtin.AtomicOrder) void{#endsyntax#}</pre> 6988 <p> 6989 This builtin function atomically stores a value. 6990 </p> 6991 <p> 6992 {#syntax#}T{#endsyntax#} must be a pointer, a {#syntax#}bool{#endsyntax#}, a float, 6993 an integer or an enum. 6994 </p> 6995 {#header_close#} 6996 {#header_open|@bitCast#} 6997 <pre>{#syntax#}@bitCast(comptime DestType: type, value: anytype) DestType{#endsyntax#}</pre> 6998 <p> 6999 Converts a value of one type to another type. 7000 </p> 7001 <p> 7002 Asserts that {#syntax#}@sizeOf(@TypeOf(value)) == @sizeOf(DestType){#endsyntax#}. 7003 </p> 7004 <p> 7005 Asserts that {#syntax#}@typeInfo(DestType) != .Pointer{#endsyntax#}. Use {#syntax#}@ptrCast{#endsyntax#} or {#syntax#}@intToPtr{#endsyntax#} if you need this. 7006 </p> 7007 <p> 7008 Can be used for these things for example: 7009 </p> 7010 <ul> 7011 <li>Convert {#syntax#}f32{#endsyntax#} to {#syntax#}u32{#endsyntax#} bits</li> 7012 <li>Convert {#syntax#}i32{#endsyntax#} to {#syntax#}u32{#endsyntax#} preserving twos complement</li> 7013 </ul> 7014 <p> 7015 Works at compile-time if {#syntax#}value{#endsyntax#} is known at compile time. It's a compile error to bitcast a struct to a scalar type of the same size since structs have undefined layout. However if the struct is packed then it works. 7016 </p> 7017 {#header_close#} 7018 7019 {#header_open|@bitOffsetOf#} 7020 <pre>{#syntax#}@bitOffsetOf(comptime T: type, comptime field_name: []const u8) comptime_int{#endsyntax#}</pre> 7021 <p> 7022 Returns the bit offset of a field relative to its containing struct. 7023 </p> 7024 <p> 7025 For non {#link|packed structs|packed struct#}, this will always be divisible by {#syntax#}8{#endsyntax#}. 7026 For packed structs, non-byte-aligned fields will share a byte offset, but they will have different 7027 bit offsets. 7028 </p> 7029 {#see_also|@offsetOf#} 7030 {#header_close#} 7031 7032 {#header_open|@boolToInt#} 7033 <pre>{#syntax#}@boolToInt(value: bool) u1{#endsyntax#}</pre> 7034 <p> 7035 Converts {#syntax#}true{#endsyntax#} to {#syntax#}u1(1){#endsyntax#} and {#syntax#}false{#endsyntax#} to 7036 {#syntax#}u1(0){#endsyntax#}. 7037 </p> 7038 <p> 7039 If the value is known at compile-time, the return type is {#syntax#}comptime_int{#endsyntax#} 7040 instead of {#syntax#}u1{#endsyntax#}. 7041 </p> 7042 {#header_close#} 7043 7044 {#header_open|@bitSizeOf#} 7045 <pre>{#syntax#}@bitSizeOf(comptime T: type) comptime_int{#endsyntax#}</pre> 7046 <p> 7047 This function returns the number of bits it takes to store {#syntax#}T{#endsyntax#} in memory. 7048 The result is a target-specific compile time constant. 7049 </p> 7050 <p> 7051 This function measures the size at runtime. For types that are disallowed at runtime, such as 7052 {#syntax#}comptime_int{#endsyntax#} and {#syntax#}type{#endsyntax#}, the result is {#syntax#}0{#endsyntax#}. 7053 </p> 7054 {#see_also|@sizeOf|@typeInfo#} 7055 {#header_close#} 7056 7057 {#header_open|@breakpoint#} 7058 <pre>{#syntax#}@breakpoint(){#endsyntax#}</pre> 7059 <p> 7060 This function inserts a platform-specific debug trap instruction which causes 7061 debuggers to break there. 7062 </p> 7063 <p> 7064 This function is only valid within function scope. 7065 </p> 7066 7067 {#header_close#} 7068 {#header_open|@mulAdd#} 7069 <pre>{#syntax#}@mulAdd(comptime T: type, a: T, b: T, c: T) T{#endsyntax#}</pre> 7070 <p> 7071 Fused multiply add, similar to {#syntax#}(a * b) + c{#endsyntax#}, except 7072 only rounds once, and is thus more accurate. 7073 </p> 7074 <p> 7075 Supports Floats and Vectors of floats. 7076 </p> 7077 {#header_close#} 7078 7079 {#header_open|@byteSwap#} 7080 <pre>{#syntax#}@byteSwap(comptime T: type, operand: T) T{#endsyntax#}</pre> 7081 <p>{#syntax#}T{#endsyntax#} must be an integer type with bit count evenly divisible by 8.</p> 7082 <p>{#syntax#}operand{#endsyntax#} may be an {#link|integer|Integers#} or {#link|vector|Vectors#}.</p> 7083 <p> 7084 Swaps the byte order of the integer. This converts a big endian integer to a little endian integer, 7085 and converts a little endian integer to a big endian integer. 7086 </p> 7087 <p> 7088 Note that for the purposes of memory layout with respect to endianness, the integer type should be 7089 related to the number of bytes reported by {#link|@sizeOf#} bytes. This is demonstrated with 7090 {#syntax#}u24{#endsyntax#}. {#syntax#}@sizeOf(u24) == 4{#endsyntax#}, which means that a 7091 {#syntax#}u24{#endsyntax#} stored in memory takes 4 bytes, and those 4 bytes are what are swapped on 7092 a little vs big endian system. On the other hand, if {#syntax#}T{#endsyntax#} is specified to 7093 be {#syntax#}u24{#endsyntax#}, then only 3 bytes are reversed. 7094 </p> 7095 {#header_close#} 7096 7097 {#header_open|@bitReverse#} 7098 <pre>{#syntax#}@bitReverse(comptime T: type, integer: T) T{#endsyntax#}</pre> 7099 <p>{#syntax#}T{#endsyntax#} accepts any integer type.</p> 7100 <p> 7101 Reverses the bitpattern of an integer value, including the sign bit if applicable. 7102 </p> 7103 <p> 7104 For example 0b10110110 ({#syntax#}u8 = 182{#endsyntax#}, {#syntax#}i8 = -74{#endsyntax#}) 7105 becomes 0b01101101 ({#syntax#}u8 = 109{#endsyntax#}, {#syntax#}i8 = 109{#endsyntax#}). 7106 </p> 7107 {#header_close#} 7108 7109 {#header_open|@offsetOf#} 7110 <pre>{#syntax#}@offsetOf(comptime T: type, comptime field_name: []const u8) comptime_int{#endsyntax#}</pre> 7111 <p> 7112 Returns the byte offset of a field relative to its containing struct. 7113 </p> 7114 {#see_also|@bitOffsetOf#} 7115 {#header_close#} 7116 7117 {#header_open|@call#} 7118 <pre>{#syntax#}@call(options: std.builtin.CallOptions, function: anytype, args: anytype) anytype{#endsyntax#}</pre> 7119 <p> 7120 Calls a function, in the same way that invoking an expression with parentheses does: 7121 </p> 7122 {#code_begin|test|call#} 7123 const expect = @import("std").testing.expect; 7124 7125 test "noinline function call" { 7126 try expect(@call(.{}, add, .{3, 9}) == 12); 7127 } 7128 7129 fn add(a: i32, b: i32) i32 { 7130 return a + b; 7131 } 7132 {#code_end#} 7133 <p> 7134 {#syntax#}@call{#endsyntax#} allows more flexibility than normal function call syntax does. The 7135 {#syntax#}CallOptions{#endsyntax#} struct is reproduced here: 7136 </p> 7137 {#code_begin|syntax#} 7138 pub const CallOptions = struct { 7139 modifier: Modifier = .auto, 7140 stack: ?[]align(std.Target.stack_align) u8 = null, 7141 7142 pub const Modifier = enum { 7143 /// Equivalent to function call syntax. 7144 auto, 7145 7146 /// Equivalent to async keyword used with function call syntax. 7147 async_kw, 7148 7149 /// Prevents tail call optimization. This guarantees that the return 7150 /// address will point to the callsite, as opposed to the callsite's 7151 /// callsite. If the call is otherwise required to be tail-called 7152 /// or inlined, a compile error is emitted instead. 7153 never_tail, 7154 7155 /// Guarantees that the call will not be inlined. If the call is 7156 /// otherwise required to be inlined, a compile error is emitted instead. 7157 never_inline, 7158 7159 /// Asserts that the function call will not suspend. This allows a 7160 /// non-async function to call an async function. 7161 no_async, 7162 7163 /// Guarantees that the call will be generated with tail call optimization. 7164 /// If this is not possible, a compile error is emitted instead. 7165 always_tail, 7166 7167 /// Guarantees that the call will inlined at the callsite. 7168 /// If this is not possible, a compile error is emitted instead. 7169 always_inline, 7170 7171 /// Evaluates the call at compile-time. If the call cannot be completed at 7172 /// compile-time, a compile error is emitted instead. 7173 compile_time, 7174 }; 7175 }; 7176 {#code_end#} 7177 {#header_close#} 7178 7179 {#header_open|@cDefine#} 7180 <pre>{#syntax#}@cDefine(comptime name: []u8, value){#endsyntax#}</pre> 7181 <p> 7182 This function can only occur inside {#syntax#}@cImport{#endsyntax#}. 7183 </p> 7184 <p> 7185 This appends <code>#define $name $value</code> to the {#syntax#}@cImport{#endsyntax#} 7186 temporary buffer. 7187 </p> 7188 <p> 7189 To define without a value, like this: 7190 </p> 7191 <pre><code class="c">#define _GNU_SOURCE</code></pre> 7192 <p> 7193 Use the void value, like this: 7194 </p> 7195 <pre>{#syntax#}@cDefine("_GNU_SOURCE", {}){#endsyntax#}</pre> 7196 {#see_also|Import from C Header File|@cInclude|@cImport|@cUndef|void#} 7197 {#header_close#} 7198 {#header_open|@cImport#} 7199 <pre>{#syntax#}@cImport(expression) type{#endsyntax#}</pre> 7200 <p> 7201 This function parses C code and imports the functions, types, variables, 7202 and compatible macro definitions into a new empty struct type, and then 7203 returns that type. 7204 </p> 7205 <p> 7206 {#syntax#}expression{#endsyntax#} is interpreted at compile time. The builtin functions 7207 {#syntax#}@cInclude{#endsyntax#}, {#syntax#}@cDefine{#endsyntax#}, and {#syntax#}@cUndef{#endsyntax#} work 7208 within this expression, appending to a temporary buffer which is then parsed as C code. 7209 </p> 7210 <p> 7211 Usually you should only have one {#syntax#}@cImport{#endsyntax#} in your entire application, because it saves the compiler 7212 from invoking clang multiple times, and prevents inline functions from being duplicated. 7213 </p> 7214 <p> 7215 Reasons for having multiple {#syntax#}@cImport{#endsyntax#} expressions would be: 7216 </p> 7217 <ul> 7218 <li>To avoid a symbol collision, for example if foo.h and bar.h both <code>#define CONNECTION_COUNT</code></li> 7219 <li>To analyze the C code with different preprocessor defines</li> 7220 </ul> 7221 {#see_also|Import from C Header File|@cInclude|@cDefine|@cUndef#} 7222 {#header_close#} 7223 {#header_open|@cInclude#} 7224 <pre>{#syntax#}@cInclude(comptime path: []u8){#endsyntax#}</pre> 7225 <p> 7226 This function can only occur inside {#syntax#}@cImport{#endsyntax#}. 7227 </p> 7228 <p> 7229 This appends <code>#include <$path>\n</code> to the {#syntax#}c_import{#endsyntax#} 7230 temporary buffer. 7231 </p> 7232 {#see_also|Import from C Header File|@cImport|@cDefine|@cUndef#} 7233 {#header_close#} 7234 7235 {#header_open|@clz#} 7236 <pre>{#syntax#}@clz(comptime T: type, integer: T){#endsyntax#}</pre> 7237 <p> 7238 This function counts the number of most-significant (leading in a big-Endian sense) zeroes in {#syntax#}integer{#endsyntax#}. 7239 </p> 7240 <p> 7241 If {#syntax#}integer{#endsyntax#} is known at {#link|comptime#}, 7242 the return type is {#syntax#}comptime_int{#endsyntax#}. 7243 Otherwise, the return type is an unsigned integer with the minimum number 7244 of bits that can represent the bit count of the integer type. 7245 </p> 7246 <p> 7247 If {#syntax#}integer{#endsyntax#} is zero, {#syntax#}@clz{#endsyntax#} returns the bit width 7248 of integer type {#syntax#}T{#endsyntax#}. 7249 </p> 7250 {#see_also|@ctz|@popCount#} 7251 {#header_close#} 7252 7253 {#header_open|@cmpxchgStrong#} 7254 <pre>{#syntax#}@cmpxchgStrong(comptime T: type, ptr: *T, expected_value: T, new_value: T, success_order: AtomicOrder, fail_order: AtomicOrder) ?T{#endsyntax#}</pre> 7255 <p> 7256 This function performs a strong atomic compare exchange operation. It's the equivalent of this code, 7257 except atomic: 7258 </p> 7259 {#code_begin|syntax#} 7260 fn cmpxchgStrongButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_value: T) ?T { 7261 const old_value = ptr.*; 7262 if (old_value == expected_value) { 7263 ptr.* = new_value; 7264 return null; 7265 } else { 7266 return old_value; 7267 } 7268 } 7269 {#code_end#} 7270 <p> 7271 If you are using cmpxchg in a loop, {#link|@cmpxchgWeak#} is the better choice, because it can be implemented 7272 more efficiently in machine instructions. 7273 </p> 7274 <p> 7275 {#syntax#}T{#endsyntax#} must be a pointer, a {#syntax#}bool{#endsyntax#}, a float, 7276 an integer or an enum. 7277 </p> 7278 <p>{#syntax#}@typeInfo(@TypeOf(ptr)).Pointer.alignment{#endsyntax#} must be {#syntax#}>= @sizeOf(T).{#endsyntax#}</p> 7279 {#see_also|Compile Variables|cmpxchgWeak#} 7280 {#header_close#} 7281 {#header_open|@cmpxchgWeak#} 7282 <pre>{#syntax#}@cmpxchgWeak(comptime T: type, ptr: *T, expected_value: T, new_value: T, success_order: AtomicOrder, fail_order: AtomicOrder) ?T{#endsyntax#}</pre> 7283 <p> 7284 This function performs a weak atomic compare exchange operation. It's the equivalent of this code, 7285 except atomic: 7286 </p> 7287 {#code_begin|syntax#} 7288 fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_value: T) ?T { 7289 const old_value = ptr.*; 7290 if (old_value == expected_value and usuallyTrueButSometimesFalse()) { 7291 ptr.* = new_value; 7292 return null; 7293 } else { 7294 return old_value; 7295 } 7296 } 7297 {#code_end#} 7298 <p> 7299 If you are using cmpxchg in a loop, the sporadic failure will be no problem, and {#syntax#}cmpxchgWeak{#endsyntax#} 7300 is the better choice, because it can be implemented more efficiently in machine instructions. 7301 However if you need a stronger guarantee, use {#link|@cmpxchgStrong#}. 7302 </p> 7303 <p> 7304 {#syntax#}T{#endsyntax#} must be a pointer, a {#syntax#}bool{#endsyntax#}, a float, 7305 an integer or an enum. 7306 </p> 7307 <p>{#syntax#}@typeInfo(@TypeOf(ptr)).Pointer.alignment{#endsyntax#} must be {#syntax#}>= @sizeOf(T).{#endsyntax#}</p> 7308 {#see_also|Compile Variables|cmpxchgStrong#} 7309 {#header_close#} 7310 7311 {#header_open|@compileError#} 7312 <pre>{#syntax#}@compileError(comptime msg: []u8){#endsyntax#}</pre> 7313 <p> 7314 This function, when semantically analyzed, causes a compile error with the 7315 message {#syntax#}msg{#endsyntax#}. 7316 </p> 7317 <p> 7318 There are several ways that code avoids being semantically checked, such as 7319 using {#syntax#}if{#endsyntax#} or {#syntax#}switch{#endsyntax#} with compile time constants, 7320 and {#syntax#}comptime{#endsyntax#} functions. 7321 </p> 7322 {#header_close#} 7323 7324 {#header_open|@compileLog#} 7325 <pre>{#syntax#}@compileLog(args: ...){#endsyntax#}</pre> 7326 <p> 7327 This function prints the arguments passed to it at compile-time. 7328 </p> 7329 <p> 7330 To prevent accidentally leaving compile log statements in a codebase, 7331 a compilation error is added to the build, pointing to the compile 7332 log statement. This error prevents code from being generated, but 7333 does not otherwise interfere with analysis. 7334 </p> 7335 <p> 7336 This function can be used to do "printf debugging" on 7337 compile-time executing code. 7338 </p> 7339 {#code_begin|test_err|found compile log statement#} 7340 const print = @import("std").debug.print; 7341 7342 const num1 = blk: { 7343 var val1: i32 = 99; 7344 @compileLog("comptime val1 = ", val1); 7345 val1 = val1 + 1; 7346 break :blk val1; 7347 }; 7348 7349 test "main" { 7350 @compileLog("comptime in main"); 7351 7352 print("Runtime in main, num1 = {}.\n", .{num1}); 7353 } 7354 {#code_end#} 7355 <p> 7356 will ouput: 7357 </p> 7358 <p> 7359 If all {#syntax#}@compileLog{#endsyntax#} calls are removed or 7360 not encountered by analysis, the 7361 program compiles successfully and the generated executable prints: 7362 </p> 7363 {#code_begin|test#} 7364 const print = @import("std").debug.print; 7365 7366 const num1 = blk: { 7367 var val1: i32 = 99; 7368 val1 = val1 + 1; 7369 break :blk val1; 7370 }; 7371 7372 test "main" { 7373 print("Runtime in main, num1 = {}.\n", .{num1}); 7374 } 7375 {#code_end#} 7376 {#header_close#} 7377 7378 {#header_open|@ctz#} 7379 <pre>{#syntax#}@ctz(comptime T: type, integer: T){#endsyntax#}</pre> 7380 <p> 7381 This function counts the number of least-significant (trailing in a big-Endian sense) zeroes in {#syntax#}integer{#endsyntax#}. 7382 </p> 7383 <p> 7384 If {#syntax#}integer{#endsyntax#} is known at {#link|comptime#}, 7385 the return type is {#syntax#}comptime_int{#endsyntax#}. 7386 Otherwise, the return type is an unsigned integer with the minimum number 7387 of bits that can represent the bit count of the integer type. 7388 </p> 7389 <p> 7390 If {#syntax#}integer{#endsyntax#} is zero, {#syntax#}@ctz{#endsyntax#} returns 7391 the bit width of integer type {#syntax#}T{#endsyntax#}. 7392 </p> 7393 {#see_also|@clz|@popCount#} 7394 {#header_close#} 7395 7396 {#header_open|@cUndef#} 7397 <pre>{#syntax#}@cUndef(comptime name: []u8){#endsyntax#}</pre> 7398 <p> 7399 This function can only occur inside {#syntax#}@cImport{#endsyntax#}. 7400 </p> 7401 <p> 7402 This appends <code>#undef $name</code> to the {#syntax#}@cImport{#endsyntax#} 7403 temporary buffer. 7404 </p> 7405 {#see_also|Import from C Header File|@cImport|@cDefine|@cInclude#} 7406 {#header_close#} 7407 7408 {#header_open|@divExact#} 7409 <pre>{#syntax#}@divExact(numerator: T, denominator: T) T{#endsyntax#}</pre> 7410 <p> 7411 Exact division. Caller guarantees {#syntax#}denominator != 0{#endsyntax#} and 7412 {#syntax#}@divTrunc(numerator, denominator) * denominator == numerator{#endsyntax#}. 7413 </p> 7414 <ul> 7415 <li>{#syntax#}@divExact(6, 3) == 2{#endsyntax#}</li> 7416 <li>{#syntax#}@divExact(a, b) * b == a{#endsyntax#}</li> 7417 </ul> 7418 <p>For a function that returns a possible error code, use {#syntax#}@import("std").math.divExact{#endsyntax#}.</p> 7419 {#see_also|@divTrunc|@divFloor#} 7420 {#header_close#} 7421 {#header_open|@divFloor#} 7422 <pre>{#syntax#}@divFloor(numerator: T, denominator: T) T{#endsyntax#}</pre> 7423 <p> 7424 Floored division. Rounds toward negative infinity. For unsigned integers it is 7425 the same as {#syntax#}numerator / denominator{#endsyntax#}. Caller guarantees {#syntax#}denominator != 0{#endsyntax#} and 7426 {#syntax#}!(@typeInfo(T) == .Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1){#endsyntax#}. 7427 </p> 7428 <ul> 7429 <li>{#syntax#}@divFloor(-5, 3) == -2{#endsyntax#}</li> 7430 <li>{#syntax#}(@divFloor(a, b) * b) + @mod(a, b) == a{#endsyntax#}</li> 7431 </ul> 7432 <p>For a function that returns a possible error code, use {#syntax#}@import("std").math.divFloor{#endsyntax#}.</p> 7433 {#see_also|@divTrunc|@divExact#} 7434 {#header_close#} 7435 {#header_open|@divTrunc#} 7436 <pre>{#syntax#}@divTrunc(numerator: T, denominator: T) T{#endsyntax#}</pre> 7437 <p> 7438 Truncated division. Rounds toward zero. For unsigned integers it is 7439 the same as {#syntax#}numerator / denominator{#endsyntax#}. Caller guarantees {#syntax#}denominator != 0{#endsyntax#} and 7440 {#syntax#}!(@typeInfo(T) == .Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1){#endsyntax#}. 7441 </p> 7442 <ul> 7443 <li>{#syntax#}@divTrunc(-5, 3) == -1{#endsyntax#}</li> 7444 <li>{#syntax#}(@divTrunc(a, b) * b) + @rem(a, b) == a{#endsyntax#}</li> 7445 </ul> 7446 <p>For a function that returns a possible error code, use {#syntax#}@import("std").math.divTrunc{#endsyntax#}.</p> 7447 {#see_also|@divFloor|@divExact#} 7448 {#header_close#} 7449 {#header_open|@embedFile#} 7450 <pre>{#syntax#}@embedFile(comptime path: []const u8) *const [X:0]u8{#endsyntax#}</pre> 7451 <p> 7452 This function returns a compile time constant pointer to null-terminated, 7453 fixed-size array with length equal to the byte count of the file given by 7454 {#syntax#}path{#endsyntax#}. The contents of the array are the contents of the file. 7455 This is equivalent to a {#link|string literal|String Literals and Unicode Code Point Literals#} 7456 with the file contents. 7457 </p> 7458 <p> 7459 {#syntax#}path{#endsyntax#} is absolute or relative to the current file, just like {#syntax#}@import{#endsyntax#}. 7460 </p> 7461 {#see_also|@import#} 7462 {#header_close#} 7463 7464 {#header_open|@enumToInt#} 7465 <pre>{#syntax#}@enumToInt(enum_or_tagged_union: anytype) anytype{#endsyntax#}</pre> 7466 <p> 7467 Converts an enumeration value into its integer tag type. When a tagged union is passed, 7468 the tag value is used as the enumeration value. 7469 </p> 7470 <p> 7471 If there is only one possible enum value, the resut is a {#syntax#}comptime_int{#endsyntax#} 7472 known at {#link|comptime#}. 7473 </p> 7474 {#see_also|@intToEnum#} 7475 {#header_close#} 7476 7477 {#header_open|@errorName#} 7478 <pre>{#syntax#}@errorName(err: anyerror) []const u8{#endsyntax#}</pre> 7479 <p> 7480 This function returns the string representation of an error. The string representation 7481 of {#syntax#}error.OutOfMem{#endsyntax#} is {#syntax#}"OutOfMem"{#endsyntax#}. 7482 </p> 7483 <p> 7484 If there are no calls to {#syntax#}@errorName{#endsyntax#} in an entire application, 7485 or all calls have a compile-time known value for {#syntax#}err{#endsyntax#}, then no 7486 error name table will be generated. 7487 </p> 7488 {#header_close#} 7489 7490 {#header_open|@errorReturnTrace#} 7491 <pre>{#syntax#}@errorReturnTrace() ?*builtin.StackTrace{#endsyntax#}</pre> 7492 <p> 7493 If the binary is built with error return tracing, and this function is invoked in a 7494 function that calls a function with an error or error union return type, returns a 7495 stack trace object. Otherwise returns {#link|null#}. 7496 </p> 7497 {#header_close#} 7498 7499 {#header_open|@errorToInt#} 7500 <pre>{#syntax#}@errorToInt(err: anytype) std.meta.Int(.unsigned, @sizeOf(anyerror) * 8){#endsyntax#}</pre> 7501 <p> 7502 Supports the following types: 7503 </p> 7504 <ul> 7505 <li>{#link|The Global Error Set#}</li> 7506 <li>{#link|Error Set Type#}</li> 7507 <li>{#link|Error Union Type#}</li> 7508 </ul> 7509 <p> 7510 Converts an error to the integer representation of an error. 7511 </p> 7512 <p> 7513 It is generally recommended to avoid this 7514 cast, as the integer representation of an error is not stable across source code changes. 7515 </p> 7516 {#see_also|@intToError#} 7517 {#header_close#} 7518 7519 {#header_open|@errSetCast#} 7520 <pre>{#syntax#}@errSetCast(comptime T: DestType, value: anytype) DestType{#endsyntax#}</pre> 7521 <p> 7522 Converts an error value from one error set to another error set. Attempting to convert an error 7523 which is not in the destination error set results in safety-protected {#link|Undefined Behavior#}. 7524 </p> 7525 {#header_close#} 7526 7527 {#header_open|@export#} 7528 <pre>{#syntax#}@export(declaration, comptime options: std.builtin.ExportOptions) void{#endsyntax#}</pre> 7529 <p> 7530 Creates a symbol in the output object file. 7531 </p> 7532 <p> 7533 <code>declaration</code> must be one of two things: 7534 </p> 7535 <ul> 7536 <li>An identifier ({#syntax#}x{#endsyntax#}) identifying a {#link|function|Functions#} or 7537 {#link|global variable|Global Variables#}.</li> 7538 <li>Field access ({#syntax#}x.y{#endsyntax#}) looking up a {#link|function|Functions#} or 7539 {#link|global variable|Global Variables#}.</li> 7540 </ul> 7541 <p> 7542 This builtin can be called from a {#link|comptime#} block to conditionally export symbols. 7543 When <code>declaration</code> is a function with the C calling convention and 7544 {#syntax#}options.linkage{#endsyntax#} is {#syntax#}Strong{#endsyntax#}, this is equivalent to 7545 the {#syntax#}export{#endsyntax#} keyword used on a function: 7546 </p> 7547 {#code_begin|obj#} 7548 comptime { 7549 @export(internalName, .{ .name = "foo", .linkage = .Strong }); 7550 } 7551 7552 fn internalName() callconv(.C) void {} 7553 {#code_end#} 7554 <p>This is equivalent to:</p> 7555 {#code_begin|obj#} 7556 export fn foo() void {} 7557 {#code_end#} 7558 <p>Note that even when using {#syntax#}export{#endsyntax#}, {#syntax#}@"foo"{#endsyntax#} syntax can 7559 be used to choose any string for the symbol name:</p> 7560 {#code_begin|obj#} 7561 export fn @"A function name that is a complete sentence."() void {} 7562 {#code_end#} 7563 <p> 7564 When looking at the resulting object, you can see the symbol is used verbatim: 7565 </p> 7566 <pre><code>00000000000001f0 T A function name that is a complete sentence.</code></pre> 7567 {#see_also|Exporting a C Library#} 7568 {#header_close#} 7569 7570 {#header_open|@extern#} 7571 <pre>{#syntax#}@extern(T: type, comptime options: std.builtin.ExternOptions) *T{#endsyntax#}</pre> 7572 <p> 7573 Creates a reference to an external symbol in the output object file. 7574 </p> 7575 {#see_also|@export#} 7576 {#header_close#} 7577 7578 {#header_open|@fence#} 7579 <pre>{#syntax#}@fence(order: AtomicOrder){#endsyntax#}</pre> 7580 <p> 7581 The {#syntax#}fence{#endsyntax#} function is used to introduce happens-before edges between operations. 7582 </p> 7583 <p> 7584 {#syntax#}AtomicOrder{#endsyntax#} can be found with {#syntax#}@import("std").builtin.AtomicOrder{#endsyntax#}. 7585 </p> 7586 {#see_also|Compile Variables#} 7587 {#header_close#} 7588 7589 {#header_open|@field#} 7590 <pre>{#syntax#}@field(lhs: anytype, comptime field_name: []const u8) (field){#endsyntax#}</pre> 7591 <p>Performs field access by a compile-time string. Works on both fields and declarations. 7592 </p> 7593 {#code_begin|test#} 7594 const std = @import("std"); 7595 7596 const Point = struct { 7597 x: u32, 7598 y: u32, 7599 7600 pub var z: u32 = 1; 7601 }; 7602 7603 test "field access by string" { 7604 const expect = std.testing.expect; 7605 var p = Point{ .x = 0, .y = 0 }; 7606 7607 @field(p, "x") = 4; 7608 @field(p, "y") = @field(p, "x") + 1; 7609 7610 try expect(@field(p, "x") == 4); 7611 try expect(@field(p, "y") == 5); 7612 } 7613 7614 test "decl access by string" { 7615 const expect = std.testing.expect; 7616 7617 try expect(@field(Point, "z") == 1); 7618 7619 @field(Point, "z") = 2; 7620 try expect(@field(Point, "z") == 2); 7621 } 7622 {#code_end#} 7623 7624 {#header_close#} 7625 7626 {#header_open|@fieldParentPtr#} 7627 <pre>{#syntax#}@fieldParentPtr(comptime ParentType: type, comptime field_name: []const u8, 7628 field_ptr: *T) *ParentType{#endsyntax#}</pre> 7629 <p> 7630 Given a pointer to a field, returns the base pointer of a struct. 7631 </p> 7632 {#header_close#} 7633 7634 {#header_open|@floatCast#} 7635 <pre>{#syntax#}@floatCast(comptime DestType: type, value: anytype) DestType{#endsyntax#}</pre> 7636 <p> 7637 Convert from one float type to another. This cast is safe, but may cause the 7638 numeric value to lose precision. 7639 </p> 7640 {#header_close#} 7641 7642 {#header_open|@floatToInt#} 7643 <pre>{#syntax#}@floatToInt(comptime DestType: type, float: anytype) DestType{#endsyntax#}</pre> 7644 <p> 7645 Converts the integer part of a floating point number to the destination type. 7646 </p> 7647 <p> 7648 If the integer part of the floating point number cannot fit in the destination type, 7649 it invokes safety-checked {#link|Undefined Behavior#}. 7650 </p> 7651 {#see_also|@intToFloat#} 7652 {#header_close#} 7653 7654 {#header_open|@frame#} 7655 <pre>{#syntax#}@frame() *@Frame(func){#endsyntax#}</pre> 7656 <p> 7657 This function returns a pointer to the frame for a given function. This type 7658 can be {#link|coerced|Type Coercion#} to {#syntax#}anyframe->T{#endsyntax#} and 7659 to {#syntax#}anyframe{#endsyntax#}, where {#syntax#}T{#endsyntax#} is the return type 7660 of the function in scope. 7661 </p> 7662 <p> 7663 This function does not mark a suspension point, but it does cause the function in scope 7664 to become an {#link|async function|Async Functions#}. 7665 </p> 7666 {#header_close#} 7667 7668 {#header_open|@Frame#} 7669 <pre>{#syntax#}@Frame(func: anytype) type{#endsyntax#}</pre> 7670 <p> 7671 This function returns the frame type of a function. This works for {#link|Async Functions#} 7672 as well as any function without a specific calling convention. 7673 </p> 7674 <p> 7675 This type is suitable to be used as the return type of {#link|async|Async and Await#} which 7676 allows one to, for example, heap-allocate an async function frame: 7677 </p> 7678 {#code_begin|test#} 7679 const std = @import("std"); 7680 7681 test "heap allocated frame" { 7682 const frame = try std.heap.page_allocator.create(@Frame(func)); 7683 frame.* = async func(); 7684 } 7685 7686 fn func() void { 7687 suspend {} 7688 } 7689 {#code_end#} 7690 {#header_close#} 7691 7692 {#header_open|@frameAddress#} 7693 <pre>{#syntax#}@frameAddress() usize{#endsyntax#}</pre> 7694 <p> 7695 This function returns the base pointer of the current stack frame. 7696 </p> 7697 <p> 7698 The implications of this are target specific and not consistent across all 7699 platforms. The frame address may not be available in release mode due to 7700 aggressive optimizations. 7701 </p> 7702 <p> 7703 This function is only valid within function scope. 7704 </p> 7705 {#header_close#} 7706 7707 {#header_open|@frameSize#} 7708 <pre>{#syntax#}@frameSize() usize{#endsyntax#}</pre> 7709 <p> 7710 This is the same as {#syntax#}@sizeOf(@Frame(func)){#endsyntax#}, where {#syntax#}func{#endsyntax#} 7711 may be runtime-known. 7712 </p> 7713 <p> 7714 This function is typically used in conjunction with {#link|@asyncCall#}. 7715 </p> 7716 {#header_close#} 7717 7718 {#header_open|@hasDecl#} 7719 <pre>{#syntax#}@hasDecl(comptime Container: type, comptime name: []const u8) bool{#endsyntax#}</pre> 7720 <p> 7721 Returns whether or not a {#link|struct#}, {#link|enum#}, or {#link|union#} has a declaration 7722 matching {#syntax#}name{#endsyntax#}. 7723 </p> 7724 {#code_begin|test#} 7725 const std = @import("std"); 7726 const expect = std.testing.expect; 7727 7728 const Foo = struct { 7729 nope: i32, 7730 7731 pub var blah = "xxx"; 7732 const hi = 1; 7733 }; 7734 7735 test "@hasDecl" { 7736 try expect(@hasDecl(Foo, "blah")); 7737 7738 // Even though `hi` is private, @hasDecl returns true because this test is 7739 // in the same file scope as Foo. It would return false if Foo was declared 7740 // in a different file. 7741 try expect(@hasDecl(Foo, "hi")); 7742 7743 // @hasDecl is for declarations; not fields. 7744 try expect(!@hasDecl(Foo, "nope")); 7745 try expect(!@hasDecl(Foo, "nope1234")); 7746 } 7747 {#code_end#} 7748 {#see_also|@hasField#} 7749 {#header_close#} 7750 7751 {#header_open|@hasField#} 7752 <pre>{#syntax#}@hasField(comptime Container: type, comptime name: []const u8) bool{#endsyntax#}</pre> 7753 <p>Returns whether the field name of a struct, union, or enum exists.</p> 7754 <p> 7755 The result is a compile time constant. 7756 </p> 7757 <p> 7758 It does not include functions, variables, or constants. 7759 </p> 7760 {#see_also|@hasDecl#} 7761 {#header_close#} 7762 7763 {#header_open|@import#} 7764 <pre>{#syntax#}@import(comptime path: []u8) type{#endsyntax#}</pre> 7765 <p> 7766 This function finds a zig file corresponding to {#syntax#}path{#endsyntax#} and adds it to the build, 7767 if it is not already added. 7768 </p> 7769 <p> 7770 Zig source files are implicitly structs, with a name equal to the file's basename with the extension 7771 truncated. {#syntax#}@import{#endsyntax#} returns the struct type corresponding to the file. 7772 </p> 7773 <p> 7774 Declarations which have the {#syntax#}pub{#endsyntax#} keyword may be referenced from a different 7775 source file than the one they are declared in. 7776 </p> 7777 <p> 7778 {#syntax#}path{#endsyntax#} can be a relative path or it can be the name of a package. 7779 If it is a relative path, it is relative to the file that contains the {#syntax#}@import{#endsyntax#} 7780 function call. 7781 </p> 7782 <p> 7783 The following packages are always available: 7784 </p> 7785 <ul> 7786 <li>{#syntax#}@import("std"){#endsyntax#} - Zig Standard Library</li> 7787 <li>{#syntax#}@import("builtin"){#endsyntax#} - Target-specific information 7788 The command <code>zig build-exe --show-builtin</code> outputs the source to stdout for reference. 7789 </li> 7790 </ul> 7791 {#see_also|Compile Variables|@embedFile#} 7792 {#header_close#} 7793 7794 {#header_open|@intCast#} 7795 <pre>{#syntax#}@intCast(comptime DestType: type, int: anytype) DestType{#endsyntax#}</pre> 7796 <p> 7797 Converts an integer to another integer while keeping the same numerical value. 7798 Attempting to convert a number which is out of range of the destination type results in 7799 safety-protected {#link|Undefined Behavior#}. 7800 </p> 7801 <p> 7802 If {#syntax#}T{#endsyntax#} is {#syntax#}comptime_int{#endsyntax#}, 7803 then this is semantically equivalent to {#link|Type Coercion#}. 7804 </p> 7805 {#header_close#} 7806 7807 {#header_open|@intToEnum#} 7808 <pre>{#syntax#}@intToEnum(comptime DestType: type, int_value: std.meta.Tag(DestType)) DestType{#endsyntax#}</pre> 7809 <p> 7810 Converts an integer into an {#link|enum#} value. 7811 </p> 7812 <p> 7813 Attempting to convert an integer which represents no value in the chosen enum type invokes 7814 safety-checked {#link|Undefined Behavior#}. 7815 </p> 7816 {#see_also|@enumToInt#} 7817 {#header_close#} 7818 7819 {#header_open|@intToError#} 7820 <pre>{#syntax#}@intToError(value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8)) anyerror{#endsyntax#}</pre> 7821 <p> 7822 Converts from the integer representation of an error into {#link|The Global Error Set#} type. 7823 </p> 7824 <p> 7825 It is generally recommended to avoid this 7826 cast, as the integer representation of an error is not stable across source code changes. 7827 </p> 7828 <p> 7829 Attempting to convert an integer that does not correspond to any error results in 7830 safety-protected {#link|Undefined Behavior#}. 7831 </p> 7832 {#see_also|@errorToInt#} 7833 {#header_close#} 7834 7835 {#header_open|@intToFloat#} 7836 <pre>{#syntax#}@intToFloat(comptime DestType: type, int: anytype) DestType{#endsyntax#}</pre> 7837 <p> 7838 Converts an integer to the closest floating point representation. To convert the other way, use {#link|@floatToInt#}. This cast is always safe. 7839 </p> 7840 {#header_close#} 7841 7842 {#header_open|@intToPtr#} 7843 <pre>{#syntax#}@intToPtr(comptime DestType: type, address: usize) DestType{#endsyntax#}</pre> 7844 <p> 7845 Converts an integer to a {#link|pointer|Pointers#}. To convert the other way, use {#link|@ptrToInt#}. 7846 </p> 7847 <p> 7848 If the destination pointer type does not allow address zero and {#syntax#}address{#endsyntax#} 7849 is zero, this invokes safety-checked {#link|Undefined Behavior#}. 7850 </p> 7851 {#header_close#} 7852 7853 {#header_open|@memcpy#} 7854 <pre>{#syntax#}@memcpy(noalias dest: [*]u8, noalias source: [*]const u8, byte_count: usize){#endsyntax#}</pre> 7855 <p> 7856 This function copies bytes from one region of memory to another. {#syntax#}dest{#endsyntax#} and 7857 {#syntax#}source{#endsyntax#} are both pointers and must not overlap. 7858 </p> 7859 <p> 7860 This function is a low level intrinsic with no safety mechanisms. Most code 7861 should not use this function, instead using something like this: 7862 </p> 7863 <pre>{#syntax#}for (source[0..byte_count]) |b, i| dest[i] = b;{#endsyntax#}</pre> 7864 <p> 7865 The optimizer is intelligent enough to turn the above snippet into a memcpy. 7866 </p> 7867 <p>There is also a standard library function for this:</p> 7868 <pre>{#syntax#}const mem = @import("std").mem; 7869 mem.copy(u8, dest[0..byte_count], source[0..byte_count]);{#endsyntax#}</pre> 7870 {#header_close#} 7871 7872 {#header_open|@memset#} 7873 <pre>{#syntax#}@memset(dest: [*]u8, c: u8, byte_count: usize){#endsyntax#}</pre> 7874 <p> 7875 This function sets a region of memory to {#syntax#}c{#endsyntax#}. {#syntax#}dest{#endsyntax#} is a pointer. 7876 </p> 7877 <p> 7878 This function is a low level intrinsic with no safety mechanisms. Most 7879 code should not use this function, instead using something like this: 7880 </p> 7881 <pre>{#syntax#}for (dest[0..byte_count]) |*b| b.* = c;{#endsyntax#}</pre> 7882 <p> 7883 The optimizer is intelligent enough to turn the above snippet into a memset. 7884 </p> 7885 <p>There is also a standard library function for this:</p> 7886 <pre>{#syntax#}const mem = @import("std").mem; 7887 mem.set(u8, dest, c);{#endsyntax#}</pre> 7888 {#header_close#} 7889 7890 {#header_open|@wasmMemorySize#} 7891 <pre>{#syntax#}@wasmMemorySize(index: u32) u32{#endsyntax#}</pre> 7892 <p> 7893 This function returns the size of the Wasm memory identified by {#syntax#}index{#endsyntax#} as 7894 an unsigned value in units of Wasm pages. Note that each Wasm page is 64KB in size. 7895 </p> 7896 <p> 7897 This function is a low level intrinsic with no safety mechanisms usually useful for allocator 7898 designers targeting Wasm. So unless you are writing a new allocator from scratch, you should use 7899 something like {#syntax#}@import("std").heap.WasmPageAllocator{#endsyntax#}. 7900 </p> 7901 {#see_also|@wasmMemoryGrow#} 7902 {#header_close#} 7903 7904 {#header_open|@wasmMemoryGrow#} 7905 <pre>{#syntax#}@wasmMemoryGrow(index: u32, delta: u32) i32{#endsyntax#}</pre> 7906 <p> 7907 This function increases the size of the Wasm memory identified by {#syntax#}index{#endsyntax#} by 7908 {#syntax#}delta{#endsyntax#} in units of unsigned number of Wasm pages. Note that each Wasm page 7909 is 64KB in size. On success, returns previous memory size; on failure, if the allocation fails, 7910 returns -1. 7911 </p> 7912 <p> 7913 This function is a low level intrinsic with no safety mechanisms usually useful for allocator 7914 designers targeting Wasm. So unless you are writing a new allocator from scratch, you should use 7915 something like {#syntax#}@import("std").heap.WasmPageAllocator{#endsyntax#}. 7916 </p> 7917 {#code_begin|test#} 7918 const std = @import("std"); 7919 const native_arch = @import("builtin").target.cpu.arch; 7920 const expect = std.testing.expect; 7921 7922 test "@wasmMemoryGrow" { 7923 if (native_arch != .wasm32) return error.SkipZigTest; 7924 7925 var prev = @wasmMemorySize(0); 7926 try expect(prev == @wasmMemoryGrow(0, 1)); 7927 try expect(prev + 1 == @wasmMemorySize(0)); 7928 } 7929 {#code_end#} 7930 {#see_also|@wasmMemorySize#} 7931 {#header_close#} 7932 7933 {#header_open|@mod#} 7934 <pre>{#syntax#}@mod(numerator: T, denominator: T) T{#endsyntax#}</pre> 7935 <p> 7936 Modulus division. For unsigned integers this is the same as 7937 {#syntax#}numerator % denominator{#endsyntax#}. Caller guarantees {#syntax#}denominator > 0{#endsyntax#}. 7938 </p> 7939 <ul> 7940 <li>{#syntax#}@mod(-5, 3) == 1{#endsyntax#}</li> 7941 <li>{#syntax#}(@divFloor(a, b) * b) + @mod(a, b) == a{#endsyntax#}</li> 7942 </ul> 7943 <p>For a function that returns an error code, see {#syntax#}@import("std").math.mod{#endsyntax#}.</p> 7944 {#see_also|@rem#} 7945 {#header_close#} 7946 7947 {#header_open|@mulWithOverflow#} 7948 <pre>{#syntax#}@mulWithOverflow(comptime T: type, a: T, b: T, result: *T) bool{#endsyntax#}</pre> 7949 <p> 7950 Performs {#syntax#}result.* = a * b{#endsyntax#}. If overflow or underflow occurs, 7951 stores the overflowed bits in {#syntax#}result{#endsyntax#} and returns {#syntax#}true{#endsyntax#}. 7952 If no overflow or underflow occurs, returns {#syntax#}false{#endsyntax#}. 7953 </p> 7954 {#header_close#} 7955 7956 {#header_open|@panic#} 7957 <pre>{#syntax#}@panic(message: []const u8) noreturn{#endsyntax#}</pre> 7958 <p> 7959 Invokes the panic handler function. By default the panic handler function 7960 calls the public {#syntax#}panic{#endsyntax#} function exposed in the root source file, or 7961 if there is not one specified, the {#syntax#}std.builtin.default_panic{#endsyntax#} 7962 function from {#syntax#}std/builtin.zig{#endsyntax#}. 7963 </p> 7964 <p>Generally it is better to use {#syntax#}@import("std").debug.panic{#endsyntax#}. 7965 However, {#syntax#}@panic{#endsyntax#} can be useful for 2 scenarios: 7966 </p> 7967 <ul> 7968 <li>From library code, calling the programmer's panic function if they exposed one in the root source file.</li> 7969 <li>When mixing C and Zig code, calling the canonical panic implementation across multiple .o files.</li> 7970 </ul> 7971 {#see_also|Root Source File#} 7972 {#header_close#} 7973 7974 {#header_open|@popCount#} 7975 <pre>{#syntax#}@popCount(comptime T: type, integer: T){#endsyntax#}</pre> 7976 <p>Counts the number of bits set in an integer.</p> 7977 <p> 7978 If {#syntax#}integer{#endsyntax#} is known at {#link|comptime#}, 7979 the return type is {#syntax#}comptime_int{#endsyntax#}. 7980 Otherwise, the return type is an unsigned integer with the minimum number 7981 of bits that can represent the bit count of the integer type. 7982 </p> 7983 {#see_also|@ctz|@clz#} 7984 {#header_close#} 7985 7986 {#header_open|@ptrCast#} 7987 <pre>{#syntax#}@ptrCast(comptime DestType: type, value: anytype) DestType{#endsyntax#}</pre> 7988 <p> 7989 Converts a pointer of one type to a pointer of another type. 7990 </p> 7991 <p> 7992 {#link|Optional Pointers#} are allowed. Casting an optional pointer which is {#link|null#} 7993 to a non-optional pointer invokes safety-checked {#link|Undefined Behavior#}. 7994 </p> 7995 {#header_close#} 7996 7997 {#header_open|@ptrToInt#} 7998 <pre>{#syntax#}@ptrToInt(value: anytype) usize{#endsyntax#}</pre> 7999 <p> 8000 Converts {#syntax#}value{#endsyntax#} to a {#syntax#}usize{#endsyntax#} which is the address of the pointer. {#syntax#}value{#endsyntax#} can be one of these types: 8001 </p> 8002 <ul> 8003 <li>{#syntax#}*T{#endsyntax#}</li> 8004 <li>{#syntax#}?*T{#endsyntax#}</li> 8005 <li>{#syntax#}fn(){#endsyntax#}</li> 8006 <li>{#syntax#}?fn(){#endsyntax#}</li> 8007 </ul> 8008 <p>To convert the other way, use {#link|@intToPtr#}</p> 8009 8010 {#header_close#} 8011 8012 {#header_open|@rem#} 8013 <pre>{#syntax#}@rem(numerator: T, denominator: T) T{#endsyntax#}</pre> 8014 <p> 8015 Remainder division. For unsigned integers this is the same as 8016 {#syntax#}numerator % denominator{#endsyntax#}. Caller guarantees {#syntax#}denominator > 0{#endsyntax#}. 8017 </p> 8018 <ul> 8019 <li>{#syntax#}@rem(-5, 3) == -2{#endsyntax#}</li> 8020 <li>{#syntax#}(@divTrunc(a, b) * b) + @rem(a, b) == a{#endsyntax#}</li> 8021 </ul> 8022 <p>For a function that returns an error code, see {#syntax#}@import("std").math.rem{#endsyntax#}.</p> 8023 {#see_also|@mod#} 8024 {#header_close#} 8025 8026 {#header_open|@returnAddress#} 8027 <pre>{#syntax#}@returnAddress() usize{#endsyntax#}</pre> 8028 <p> 8029 This function returns the address of the next machine code instruction that will be executed 8030 when the current function returns. 8031 </p> 8032 <p> 8033 The implications of this are target specific and not consistent across 8034 all platforms. 8035 </p> 8036 <p> 8037 This function is only valid within function scope. If the function gets inlined into 8038 a calling function, the returned address will apply to the calling function. 8039 </p> 8040 {#header_close#} 8041 {#header_open|@setAlignStack#} 8042 <pre>{#syntax#}@setAlignStack(comptime alignment: u29){#endsyntax#}</pre> 8043 <p> 8044 Ensures that a function will have a stack alignment of at least {#syntax#}alignment{#endsyntax#} bytes. 8045 </p> 8046 {#header_close#} 8047 8048 {#header_open|@setCold#} 8049 <pre>{#syntax#}@setCold(is_cold: bool){#endsyntax#}</pre> 8050 <p> 8051 Tells the optimizer that a function is rarely called. 8052 </p> 8053 {#header_close#} 8054 8055 {#header_open|@setEvalBranchQuota#} 8056 <pre>{#syntax#}@setEvalBranchQuota(new_quota: u32){#endsyntax#}</pre> 8057 <p> 8058 Changes the maximum number of backwards branches that compile-time code 8059 execution can use before giving up and making a compile error. 8060 </p> 8061 <p> 8062 If the {#syntax#}new_quota{#endsyntax#} is smaller than the default quota ({#syntax#}1000{#endsyntax#}) or 8063 a previously explicitly set quota, it is ignored. 8064 </p> 8065 <p> 8066 Example: 8067 </p> 8068 {#code_begin|test_err|evaluation exceeded 1000 backwards branches#} 8069 test "foo" { 8070 comptime { 8071 var i = 0; 8072 while (i < 1001) : (i += 1) {} 8073 } 8074 } 8075 {#code_end#} 8076 <p>Now we use {#syntax#}@setEvalBranchQuota{#endsyntax#}:</p> 8077 {#code_begin|test#} 8078 test "foo" { 8079 comptime { 8080 @setEvalBranchQuota(1001); 8081 var i = 0; 8082 while (i < 1001) : (i += 1) {} 8083 } 8084 } 8085 {#code_end#} 8086 8087 {#see_also|comptime#} 8088 {#header_close#} 8089 8090 {#header_open|@setFloatMode#} 8091 <pre>{#syntax#}@setFloatMode(mode: @import("std").builtin.FloatMode){#endsyntax#}</pre> 8092 <p> 8093 Sets the floating point mode of the current scope. Possible values are: 8094 </p> 8095 {#code_begin|syntax#} 8096 pub const FloatMode = enum { 8097 Strict, 8098 Optimized, 8099 }; 8100 {#code_end#} 8101 <ul> 8102 <li> 8103 {#syntax#}Strict{#endsyntax#} (default) - Floating point operations follow strict IEEE compliance. 8104 </li> 8105 <li> 8106 {#syntax#}Optimized{#endsyntax#} - Floating point operations may do all of the following: 8107 <ul> 8108 <li>Assume the arguments and result are not NaN. Optimizations are required to retain defined behavior over NaNs, but the value of the result is undefined.</li> 8109 <li>Assume the arguments and result are not +/-Inf. Optimizations are required to retain defined behavior over +/-Inf, but the value of the result is undefined.</li> 8110 <li>Treat the sign of a zero argument or result as insignificant.</li> 8111 <li>Use the reciprocal of an argument rather than perform division.</li> 8112 <li>Perform floating-point contraction (e.g. fusing a multiply followed by an addition into a fused multiply-and-add).</li> 8113 <li>Perform algebraically equivalent transformations that may change results in floating point (e.g. reassociate).</li> 8114 </ul> 8115 This is equivalent to <code>-ffast-math</code> in GCC. 8116 </li> 8117 </ul> 8118 <p> 8119 The floating point mode is inherited by child scopes, and can be overridden in any scope. 8120 You can set the floating point mode in a struct or module scope by using a comptime block. 8121 </p> 8122 {#see_also|Floating Point Operations#} 8123 {#header_close#} 8124 8125 {#header_open|@setRuntimeSafety#} 8126 <pre>{#syntax#}@setRuntimeSafety(safety_on: bool){#endsyntax#}</pre> 8127 <p> 8128 Sets whether runtime safety checks are enabled for the scope that contains the function call. 8129 </p> 8130 {#code_begin|test_safety|integer overflow#} 8131 {#code_release_fast#} 8132 test "@setRuntimeSafety" { 8133 // The builtin applies to the scope that it is called in. So here, integer overflow 8134 // will not be caught in ReleaseFast and ReleaseSmall modes: 8135 // var x: u8 = 255; 8136 // x += 1; // undefined behavior in ReleaseFast/ReleaseSmall modes. 8137 { 8138 // However this block has safety enabled, so safety checks happen here, 8139 // even in ReleaseFast and ReleaseSmall modes. 8140 @setRuntimeSafety(true); 8141 var x: u8 = 255; 8142 x += 1; 8143 8144 { 8145 // The value can be overridden at any scope. So here integer overflow 8146 // would not be caught in any build mode. 8147 @setRuntimeSafety(false); 8148 // var x: u8 = 255; 8149 // x += 1; // undefined behavior in all build modes. 8150 } 8151 } 8152 } 8153 {#code_end#} 8154 <p>Note: it is <a href="https://github.com/ziglang/zig/issues/978">planned</a> to replace 8155 {#syntax#}@setRuntimeSafety{#endsyntax#} with <code>@optimizeFor</code></p> 8156 8157 {#header_close#} 8158 8159 {#header_open|@shlExact#} 8160 <pre>{#syntax#}@shlExact(value: T, shift_amt: Log2T) T{#endsyntax#}</pre> 8161 <p> 8162 Performs the left shift operation ({#syntax#}<<{#endsyntax#}). Caller guarantees 8163 that the shift will not shift any 1 bits out. 8164 </p> 8165 <p> 8166 The type of {#syntax#}shift_amt{#endsyntax#} is an unsigned integer with {#syntax#}log2(T.bit_count){#endsyntax#} bits. 8167 This is because {#syntax#}shift_amt >= T.bit_count{#endsyntax#} is undefined behavior. 8168 </p> 8169 {#see_also|@shrExact|@shlWithOverflow#} 8170 {#header_close#} 8171 8172 {#header_open|@shlWithOverflow#} 8173 <pre>{#syntax#}@shlWithOverflow(comptime T: type, a: T, shift_amt: Log2T, result: *T) bool{#endsyntax#}</pre> 8174 <p> 8175 Performs {#syntax#}result.* = a << b{#endsyntax#}. If overflow or underflow occurs, 8176 stores the overflowed bits in {#syntax#}result{#endsyntax#} and returns {#syntax#}true{#endsyntax#}. 8177 If no overflow or underflow occurs, returns {#syntax#}false{#endsyntax#}. 8178 </p> 8179 <p> 8180 The type of {#syntax#}shift_amt{#endsyntax#} is an unsigned integer with {#syntax#}log2(T.bit_count){#endsyntax#} bits. 8181 This is because {#syntax#}shift_amt >= T.bit_count{#endsyntax#} is undefined behavior. 8182 </p> 8183 {#see_also|@shlExact|@shrExact#} 8184 {#header_close#} 8185 8186 {#header_open|@shrExact#} 8187 <pre>{#syntax#}@shrExact(value: T, shift_amt: Log2T) T{#endsyntax#}</pre> 8188 <p> 8189 Performs the right shift operation ({#syntax#}>>{#endsyntax#}). Caller guarantees 8190 that the shift will not shift any 1 bits out. 8191 </p> 8192 <p> 8193 The type of {#syntax#}shift_amt{#endsyntax#} is an unsigned integer with {#syntax#}log2(T.bit_count){#endsyntax#} bits. 8194 This is because {#syntax#}shift_amt >= T.bit_count{#endsyntax#} is undefined behavior. 8195 </p> 8196 {#see_also|@shlExact|@shlWithOverflow#} 8197 {#header_close#} 8198 8199 {#header_open|@shuffle#} 8200 <pre>{#syntax#}@shuffle(comptime E: type, a: std.meta.Vector(a_len, E), b: std.meta.Vector(b_len, E), comptime mask: std.meta.Vector(mask_len, i32)) std.meta.Vector(mask_len, E){#endsyntax#}</pre> 8201 <p> 8202 Constructs a new {#link|vector|Vectors#} by selecting elements from {#syntax#}a{#endsyntax#} and 8203 {#syntax#}b{#endsyntax#} based on {#syntax#}mask{#endsyntax#}. 8204 </p> 8205 <p> 8206 Each element in {#syntax#}mask{#endsyntax#} selects an element from either {#syntax#}a{#endsyntax#} or 8207 {#syntax#}b{#endsyntax#}. Positive numbers select from {#syntax#}a{#endsyntax#} starting at 0. 8208 Negative values select from {#syntax#}b{#endsyntax#}, starting at {#syntax#}-1{#endsyntax#} and going down. 8209 It is recommended to use the {#syntax#}~{#endsyntax#} operator from indexes from {#syntax#}b{#endsyntax#} 8210 so that both indexes can start from {#syntax#}0{#endsyntax#} (i.e. {#syntax#}~@as(i32, 0){#endsyntax#} is 8211 {#syntax#}-1{#endsyntax#}). 8212 </p> 8213 <p> 8214 For each element of {#syntax#}mask{#endsyntax#}, if it or the selected value from 8215 {#syntax#}a{#endsyntax#} or {#syntax#}b{#endsyntax#} is {#syntax#}undefined{#endsyntax#}, 8216 then the resulting element is {#syntax#}undefined{#endsyntax#}. 8217 </p> 8218 <p> 8219 {#syntax#}a_len{#endsyntax#} and {#syntax#}b_len{#endsyntax#} may differ in length. Out-of-bounds element 8220 indexes in {#syntax#}mask{#endsyntax#} result in compile errors. 8221 </p> 8222 <p> 8223 If {#syntax#}a{#endsyntax#} or {#syntax#}b{#endsyntax#} is {#syntax#}undefined{#endsyntax#}, it 8224 is equivalent to a vector of all {#syntax#}undefined{#endsyntax#} with the same length as the other vector. 8225 If both vectors are {#syntax#}undefined{#endsyntax#}, {#syntax#}@shuffle{#endsyntax#} returns 8226 a vector with all elements {#syntax#}undefined{#endsyntax#}. 8227 </p> 8228 <p> 8229 {#syntax#}E{#endsyntax#} must be an {#link|integer|Integers#}, {#link|float|Floats#}, 8230 {#link|pointer|Pointers#}, or {#syntax#}bool{#endsyntax#}. The mask may be any vector length, and its 8231 length determines the result length. 8232 </p> 8233 {#see_also|SIMD#} 8234 {#header_close#} 8235 8236 {#header_open|@sizeOf#} 8237 <pre>{#syntax#}@sizeOf(comptime T: type) comptime_int{#endsyntax#}</pre> 8238 <p> 8239 This function returns the number of bytes it takes to store {#syntax#}T{#endsyntax#} in memory. 8240 The result is a target-specific compile time constant. 8241 </p> 8242 <p> 8243 This size may contain padding bytes. If there were two consecutive T in memory, this would be the offset 8244 in bytes between element at index 0 and the element at index 1. For {#link|integer|Integers#}, 8245 consider whether you want to use {#syntax#}@sizeOf(T){#endsyntax#} or 8246 {#syntax#}@typeInfo(T).Int.bits{#endsyntax#}. 8247 </p> 8248 <p> 8249 This function measures the size at runtime. For types that are disallowed at runtime, such as 8250 {#syntax#}comptime_int{#endsyntax#} and {#syntax#}type{#endsyntax#}, the result is {#syntax#}0{#endsyntax#}. 8251 </p> 8252 {#see_also|@bitSizeOf|@typeInfo#} 8253 {#header_close#} 8254 8255 {#header_open|@splat#} 8256 <pre>{#syntax#}@splat(comptime len: u32, scalar: anytype) std.meta.Vector(len, @TypeOf(scalar)){#endsyntax#}</pre> 8257 <p> 8258 Produces a vector of length {#syntax#}len{#endsyntax#} where each element is the value 8259 {#syntax#}scalar{#endsyntax#}: 8260 </p> 8261 {#code_begin|test#} 8262 const std = @import("std"); 8263 const expect = std.testing.expect; 8264 8265 test "vector @splat" { 8266 const scalar: u32 = 5; 8267 const result = @splat(4, scalar); 8268 comptime try expect(@TypeOf(result) == std.meta.Vector(4, u32)); 8269 try expect(std.mem.eql(u32, &@as([4]u32, result), &[_]u32{ 5, 5, 5, 5 })); 8270 } 8271 {#code_end#} 8272 <p> 8273 {#syntax#}scalar{#endsyntax#} must be an {#link|integer|Integers#}, {#link|bool|Primitive Types#}, 8274 {#link|float|Floats#}, or {#link|pointer|Pointers#}. 8275 </p> 8276 {#see_also|Vectors|@shuffle#} 8277 {#header_close#} 8278 8279 {#header_open|@reduce#} 8280 <pre>{#syntax#}@reduce(comptime op: std.builtin.ReduceOp, value: anytype) std.meta.Child(value){#endsyntax#}</pre> 8281 <p> 8282 Transforms a {#link|vector|Vectors#} into a scalar value by performing a 8283 sequential horizontal reduction of its elements using the specified operator {#syntax#}op{#endsyntax#}. 8284 </p> 8285 <p> 8286 Not every operator is available for every vector element type: 8287 </p> 8288 <ul> 8289 <li>{#syntax#}.And{#endsyntax#}, {#syntax#}.Or{#endsyntax#}, 8290 {#syntax#}.Xor{#endsyntax#} are available for 8291 {#syntax#}bool{#endsyntax#} vectors,</li> 8292 <li>{#syntax#}.Min{#endsyntax#}, {#syntax#}.Max{#endsyntax#}, 8293 {#syntax#}.Add{#endsyntax#}, {#syntax#}.Mul{#endsyntax#} are 8294 available for {#link|floating point|Floats#} vectors,</li> 8295 <li>Every operator is available for {#link|integer|Integers#} vectors. 8296 </ul> 8297 <p> 8298 Note that {#syntax#}.Add{#endsyntax#} and {#syntax#}.Mul{#endsyntax#} 8299 reductions on integral types are wrapping; when applied on floating point 8300 types the operation associativity is preserved, unless the float mode is 8301 set to {#syntax#}Optimized{#endsyntax#}. 8302 </p> 8303 {#code_begin|test#} 8304 const std = @import("std"); 8305 const expect = std.testing.expect; 8306 8307 test "vector @reduce" { 8308 const value: std.meta.Vector(4, i32) = [_]i32{ 1, -1, 1, -1 }; 8309 const result = value > @splat(4, @as(i32, 0)); 8310 // result is { true, false, true, false }; 8311 comptime try expect(@TypeOf(result) == std.meta.Vector(4, bool)); 8312 const is_all_true = @reduce(.And, result); 8313 comptime try expect(@TypeOf(is_all_true) == bool); 8314 try expect(is_all_true == false); 8315 } 8316 {#code_end#} 8317 {#see_also|Vectors|@setFloatMode#} 8318 {#header_close#} 8319 8320 {#header_open|@src#} 8321 <pre>{#syntax#}@src() std.builtin.SourceLocation{#endsyntax#}</pre> 8322 <p> 8323 Returns a {#syntax#}SourceLocation{#endsyntax#} struct representing the function's name and location in the source code. This must be called in a function. 8324 </p> 8325 {#code_begin|test#} 8326 const std = @import("std"); 8327 const expect = std.testing.expect; 8328 8329 test "@src" { 8330 try doTheTest(); 8331 } 8332 8333 fn doTheTest() !void { 8334 const src = @src(); 8335 8336 try expect(src.line == 9); 8337 try expect(src.column == 17); 8338 try expect(std.mem.endsWith(u8, src.fn_name, "doTheTest")); 8339 try expect(std.mem.endsWith(u8, src.file, "test.zig")); 8340 } 8341 {#code_end#} 8342 {#header_close#} 8343 {#header_open|@sqrt#} 8344 <pre>{#syntax#}@sqrt(value: anytype) @TypeOf(value){#endsyntax#}</pre> 8345 <p> 8346 Performs the square root of a floating point number. Uses a dedicated hardware instruction 8347 when available. 8348 </p> 8349 <p> 8350 Supports {#link|Floats#} and {#link|Vectors#} of floats, with the caveat that 8351 <a href="https://github.com/ziglang/zig/issues/4026">some float operations are not yet implemented for all float types</a>. 8352 </p> 8353 {#header_close#} 8354 {#header_open|@sin#} 8355 <pre>{#syntax#}@sin(value: anytype) @TypeOf(value){#endsyntax#}</pre> 8356 <p> 8357 Sine trigometric function on a floating point number. Uses a dedicated hardware instruction 8358 when available. 8359 </p> 8360 <p> 8361 Supports {#link|Floats#} and {#link|Vectors#} of floats, with the caveat that 8362 <a href="https://github.com/ziglang/zig/issues/4026">some float operations are not yet implemented for all float types</a>. 8363 </p> 8364 {#header_close#} 8365 {#header_open|@cos#} 8366 <pre>{#syntax#}@cos(value: anytype) @TypeOf(value){#endsyntax#}</pre> 8367 <p> 8368 Cosine trigometric function on a floating point number. Uses a dedicated hardware instruction 8369 when available. 8370 </p> 8371 <p> 8372 Supports {#link|Floats#} and {#link|Vectors#} of floats, with the caveat that 8373 <a href="https://github.com/ziglang/zig/issues/4026">some float operations are not yet implemented for all float types</a>. 8374 </p> 8375 {#header_close#} 8376 {#header_open|@exp#} 8377 <pre>{#syntax#}@exp(value: anytype) @TypeOf(value){#endsyntax#}</pre> 8378 <p> 8379 Base-e exponential function on a floating point number. Uses a dedicated hardware instruction 8380 when available. 8381 </p> 8382 <p> 8383 Supports {#link|Floats#} and {#link|Vectors#} of floats, with the caveat that 8384 <a href="https://github.com/ziglang/zig/issues/4026">some float operations are not yet implemented for all float types</a>. 8385 </p> 8386 {#header_close#} 8387 {#header_open|@exp2#} 8388 <pre>{#syntax#}@exp2(value: anytype) @TypeOf(value){#endsyntax#}</pre> 8389 <p> 8390 Base-2 exponential function on a floating point number. Uses a dedicated hardware instruction 8391 when available. 8392 </p> 8393 <p> 8394 Supports {#link|Floats#} and {#link|Vectors#} of floats, with the caveat that 8395 <a href="https://github.com/ziglang/zig/issues/4026">some float operations are not yet implemented for all float types</a>. 8396 </p> 8397 {#header_close#} 8398 {#header_open|@log#} 8399 <pre>{#syntax#}@log(value: anytype) @TypeOf(value){#endsyntax#}</pre> 8400 <p> 8401 Returns the natural logarithm of a floating point number. Uses a dedicated hardware instruction 8402 when available. 8403 </p> 8404 <p> 8405 Supports {#link|Floats#} and {#link|Vectors#} of floats, with the caveat that 8406 <a href="https://github.com/ziglang/zig/issues/4026">some float operations are not yet implemented for all float types</a>. 8407 </p> 8408 {#header_close#} 8409 {#header_open|@log2#} 8410 <pre>{#syntax#}@log2(value: anytype) @TypeOf(value){#endsyntax#}</pre> 8411 <p> 8412 Returns the logarithm to the base 2 of a floating point number. Uses a dedicated hardware instruction 8413 when available. 8414 </p> 8415 <p> 8416 Supports {#link|Floats#} and {#link|Vectors#} of floats, with the caveat that 8417 <a href="https://github.com/ziglang/zig/issues/4026">some float operations are not yet implemented for all float types</a>. 8418 </p> 8419 {#header_close#} 8420 {#header_open|@log10#} 8421 <pre>{#syntax#}@log10(value: anytype) @TypeOf(value){#endsyntax#}</pre> 8422 <p> 8423 Returns the logarithm to the base 10 of a floating point number. Uses a dedicated hardware instruction 8424 when available. 8425 </p> 8426 <p> 8427 Supports {#link|Floats#} and {#link|Vectors#} of floats, with the caveat that 8428 <a href="https://github.com/ziglang/zig/issues/4026">some float operations are not yet implemented for all float types</a>. 8429 </p> 8430 {#header_close#} 8431 {#header_open|@fabs#} 8432 <pre>{#syntax#}@fabs(value: anytype) @TypeOf(value){#endsyntax#}</pre> 8433 <p> 8434 Returns the absolute value of a floating point number. Uses a dedicated hardware instruction 8435 when available. 8436 </p> 8437 <p> 8438 Supports {#link|Floats#} and {#link|Vectors#} of floats, with the caveat that 8439 <a href="https://github.com/ziglang/zig/issues/4026">some float operations are not yet implemented for all float types</a>. 8440 </p> 8441 {#header_close#} 8442 {#header_open|@floor#} 8443 <pre>{#syntax#}@floor(value: anytype) @TypeOf(value){#endsyntax#}</pre> 8444 <p> 8445 Returns the largest integral value not greater than the given floating point number. 8446 Uses a dedicated hardware instruction when available. 8447 </p> 8448 <p> 8449 Supports {#link|Floats#} and {#link|Vectors#} of floats, with the caveat that 8450 <a href="https://github.com/ziglang/zig/issues/4026">some float operations are not yet implemented for all float types</a>. 8451 </p> 8452 {#header_close#} 8453 {#header_open|@ceil#} 8454 <pre>{#syntax#}@ceil(value: anytype) @TypeOf(value){#endsyntax#}</pre> 8455 <p> 8456 Returns the largest integral value not less than the given floating point number. 8457 Uses a dedicated hardware instruction when available. 8458 </p> 8459 <p> 8460 Supports {#link|Floats#} and {#link|Vectors#} of floats, with the caveat that 8461 <a href="https://github.com/ziglang/zig/issues/4026">some float operations are not yet implemented for all float types</a>. 8462 </p> 8463 {#header_close#} 8464 {#header_open|@trunc#} 8465 <pre>{#syntax#}@trunc(value: anytype) @TypeOf(value){#endsyntax#}</pre> 8466 <p> 8467 Rounds the given floating point number to an integer, towards zero. 8468 Uses a dedicated hardware instruction when available. 8469 </p> 8470 <p> 8471 Supports {#link|Floats#} and {#link|Vectors#} of floats, with the caveat that 8472 <a href="https://github.com/ziglang/zig/issues/4026">some float operations are not yet implemented for all float types</a>. 8473 </p> 8474 {#header_close#} 8475 {#header_open|@round#} 8476 <pre>{#syntax#}@round(value: anytype) @TypeOf(value){#endsyntax#}</pre> 8477 <p> 8478 Rounds the given floating point number to an integer, away from zero. Uses a dedicated hardware instruction 8479 when available. 8480 </p> 8481 <p> 8482 Supports {#link|Floats#} and {#link|Vectors#} of floats, with the caveat that 8483 <a href="https://github.com/ziglang/zig/issues/4026">some float operations are not yet implemented for all float types</a>. 8484 </p> 8485 {#header_close#} 8486 8487 {#header_open|@subWithOverflow#} 8488 <pre>{#syntax#}@subWithOverflow(comptime T: type, a: T, b: T, result: *T) bool{#endsyntax#}</pre> 8489 <p> 8490 Performs {#syntax#}result.* = a - b{#endsyntax#}. If overflow or underflow occurs, 8491 stores the overflowed bits in {#syntax#}result{#endsyntax#} and returns {#syntax#}true{#endsyntax#}. 8492 If no overflow or underflow occurs, returns {#syntax#}false{#endsyntax#}. 8493 </p> 8494 {#header_close#} 8495 8496 {#header_open|@tagName#} 8497 <pre>{#syntax#}@tagName(value: anytype) [:0]const u8{#endsyntax#}</pre> 8498 <p> 8499 Converts an enum value or union value to a string literal representing the name.</p><p>If the enum is non-exhaustive and the tag value does not map to a name, it invokes safety-checked {#link|Undefined Behavior#}. 8500 </p> 8501 {#header_close#} 8502 8503 {#header_open|@This#} 8504 <pre>{#syntax#}@This() type{#endsyntax#}</pre> 8505 <p> 8506 Returns the innermost struct, enum, or union that this function call is inside. 8507 This can be useful for an anonymous struct that needs to refer to itself: 8508 </p> 8509 {#code_begin|test#} 8510 const std = @import("std"); 8511 const expect = std.testing.expect; 8512 8513 test "@This()" { 8514 var items = [_]i32{ 1, 2, 3, 4 }; 8515 const list = List(i32){ .items = items[0..] }; 8516 try expect(list.length() == 4); 8517 } 8518 8519 fn List(comptime T: type) type { 8520 return struct { 8521 const Self = @This(); 8522 8523 items: []T, 8524 8525 fn length(self: Self) usize { 8526 return self.items.len; 8527 } 8528 }; 8529 } 8530 {#code_end#} 8531 <p> 8532 When {#syntax#}@This(){#endsyntax#} is used at global scope, it returns a reference to the 8533 struct that corresponds to the current file. 8534 </p> 8535 {#header_close#} 8536 8537 {#header_open|@truncate#} 8538 <pre>{#syntax#}@truncate(comptime T: type, integer: anytype) T{#endsyntax#}</pre> 8539 <p> 8540 This function truncates bits from an integer type, resulting in a smaller 8541 or same-sized integer type. 8542 </p> 8543 <p> 8544 The following produces safety-checked {#link|Undefined Behavior#}: 8545 </p> 8546 {#code_begin|test_err|cast truncated bits#} 8547 test "integer cast panic" { 8548 var a: u16 = 0xabcd; 8549 var b: u8 = @intCast(u8, a); 8550 } 8551 {#code_end#} 8552 <p> 8553 However this is well defined and working code: 8554 </p> 8555 {#code_begin|test|truncate#} 8556 const std = @import("std"); 8557 const expect = std.testing.expect; 8558 8559 test "integer truncation" { 8560 var a: u16 = 0xabcd; 8561 var b: u8 = @truncate(u8, a); 8562 try expect(b == 0xcd); 8563 } 8564 {#code_end#} 8565 <p> 8566 This function always truncates the significant bits of the integer, regardless 8567 of endianness on the target platform. 8568 </p> 8569 {#header_close#} 8570 8571 {#header_open|@Type#} 8572 <pre>{#syntax#}@Type(comptime info: std.builtin.TypeInfo) type{#endsyntax#}</pre> 8573 <p> 8574 This function is the inverse of {#link|@typeInfo#}. It reifies type information 8575 into a {#syntax#}type{#endsyntax#}. 8576 </p> 8577 <p> 8578 It is available for the following types: 8579 </p> 8580 <ul> 8581 <li>{#syntax#}type{#endsyntax#}</li> 8582 <li>{#syntax#}noreturn{#endsyntax#}</li> 8583 <li>{#syntax#}void{#endsyntax#}</li> 8584 <li>{#syntax#}bool{#endsyntax#}</li> 8585 <li>{#link|Integers#} - The maximum bit count for an integer type is {#syntax#}65535{#endsyntax#}.</li> 8586 <li>{#link|Floats#}</li> 8587 <li>{#link|Pointers#}</li> 8588 <li>{#syntax#}comptime_int{#endsyntax#}</li> 8589 <li>{#syntax#}comptime_float{#endsyntax#}</li> 8590 <li>{#syntax#}@TypeOf(undefined){#endsyntax#}</li> 8591 <li>{#syntax#}@TypeOf(null){#endsyntax#}</li> 8592 <li>{#link|Arrays#}</li> 8593 <li>{#link|Optionals#}</li> 8594 <li>{#link|Error Set Type#}</li> 8595 <li>{#link|Error Union Type#}</li> 8596 <li>{#link|Vectors#}</li> 8597 <li>{#link|opaque#}</li> 8598 <li>{#link|@Frame#}</li> 8599 <li>{#syntax#}anyframe{#endsyntax#}</li> 8600 <li>{#link|struct#}</li> 8601 <li>{#link|enum#}</li> 8602 <li>{#link|Enum Literals#}</li> 8603 <li>{#link|union#}</li> 8604 </ul> 8605 <p> 8606 For these types, {#syntax#}@Type{#endsyntax#} is not available: 8607 </p> 8608 <ul> 8609 <li>{#link|Functions#}</li> 8610 <li>BoundFn</li> 8611 </ul> 8612 {#header_close#} 8613 {#header_open|@typeInfo#} 8614 <pre>{#syntax#}@typeInfo(comptime T: type) std.builtin.TypeInfo{#endsyntax#}</pre> 8615 <p> 8616 Provides type reflection. 8617 </p> 8618 <p> 8619 For {#link|structs|struct#}, {#link|unions|union#}, {#link|enums|enum#}, and 8620 {#link|error sets|Error Set Type#}, the fields are guaranteed to be in the same 8621 order as declared. For declarations, the order is unspecified. 8622 </p> 8623 {#header_close#} 8624 8625 {#header_open|@typeName#} 8626 <pre>{#syntax#}@typeName(T: type) [N]u8{#endsyntax#}</pre> 8627 <p> 8628 This function returns the string representation of a type, as 8629 an array. It is equivalent to a string literal of the type name. 8630 </p> 8631 8632 {#header_close#} 8633 8634 {#header_open|@TypeOf#} 8635 <pre>{#syntax#}@TypeOf(...) type{#endsyntax#}</pre> 8636 <p> 8637 {#syntax#}@TypeOf{#endsyntax#} is a special builtin function that takes any (nonzero) number of expressions 8638 as parameters and returns the type of the result, using {#link|Peer Type Resolution#}. 8639 </p> 8640 <p> 8641 The expressions are evaluated, however they are guaranteed to have no <em>runtime</em> side-effects: 8642 </p> 8643 {#code_begin|test#} 8644 const std = @import("std"); 8645 const expect = std.testing.expect; 8646 8647 test "no runtime side effects" { 8648 var data: i32 = 0; 8649 const T = @TypeOf(foo(i32, &data)); 8650 comptime try expect(T == i32); 8651 try expect(data == 0); 8652 } 8653 8654 fn foo(comptime T: type, ptr: *T) T { 8655 ptr.* += 1; 8656 return ptr.*; 8657 } 8658 {#code_end#} 8659 {#header_close#} 8660 8661 {#header_open|@unionInit#} 8662 <pre>{#syntax#}@unionInit(comptime Union: type, comptime active_field_name: []const u8, init_expr) Union{#endsyntax#}</pre> 8663 <p> 8664 This is the same thing as {#link|union#} initialization syntax, except that the field name is a 8665 {#link|comptime#}-known value rather than an identifier token. 8666 </p> 8667 <p> 8668 {#syntax#}@unionInit{#endsyntax#} forwards its {#link|result location|Result Location Semantics#} to {#syntax#}init_expr{#endsyntax#}. 8669 </p> 8670 {#header_close#} 8671 {#header_close#} 8672 8673 {#header_open|Build Mode#} 8674 <p> 8675 Zig has four build modes: 8676 </p> 8677 <ul> 8678 <li>{#link|Debug#} (default)</li> 8679 <li>{#link|ReleaseFast#}</li> 8680 <li>{#link|ReleaseSafe#}</li> 8681 <li>{#link|ReleaseSmall#}</li> 8682 </ul> 8683 <p> 8684 To add standard build options to a <code>build.zig</code> file: 8685 </p> 8686 {#code_begin|syntax#} 8687 const Builder = @import("std").build.Builder; 8688 8689 pub fn build(b: *Builder) void { 8690 const exe = b.addExecutable("example", "example.zig"); 8691 exe.setBuildMode(b.standardReleaseOptions()); 8692 b.default_step.dependOn(&exe.step); 8693 } 8694 {#code_end#} 8695 <p> 8696 This causes these options to be available: 8697 </p> 8698 <pre><code class="shell"> -Drelease-safe=[bool] optimizations on and safety on 8699 -Drelease-fast=[bool] optimizations on and safety off 8700 -Drelease-small=[bool] size optimizations on and safety off</code></pre> 8701 {#header_open|Debug#} 8702 <pre><code class="shell">$ zig build-exe example.zig</code></pre> 8703 <ul> 8704 <li>Fast compilation speed</li> 8705 <li>Safety checks enabled</li> 8706 <li>Slow runtime performance</li> 8707 <li>Large binary size</li> 8708 <li>No reproducible build requirement</li> 8709 </ul> 8710 {#header_close#} 8711 {#header_open|ReleaseFast#} 8712 <pre><code class="shell">$ zig build-exe example.zig -O ReleaseFast</code></pre> 8713 <ul> 8714 <li>Fast runtime performance</li> 8715 <li>Safety checks disabled</li> 8716 <li>Slow compilation speed</li> 8717 <li>Large binary size</li> 8718 <li>Reproducible build</li> 8719 </ul> 8720 {#header_close#} 8721 {#header_open|ReleaseSafe#} 8722 <pre><code class="shell">$ zig build-exe example.zig -O ReleaseSafe</code></pre> 8723 <ul> 8724 <li>Medium runtime performance</li> 8725 <li>Safety checks enabled</li> 8726 <li>Slow compilation speed</li> 8727 <li>Large binary size</li> 8728 <li>Reproducible build</li> 8729 </ul> 8730 {#header_close#} 8731 {#header_open|ReleaseSmall#} 8732 <pre><code class="shell">$ zig build-exe example.zig -O ReleaseSmall</code></pre> 8733 <ul> 8734 <li>Medium runtime performance</li> 8735 <li>Safety checks disabled</li> 8736 <li>Slow compilation speed</li> 8737 <li>Small binary size</li> 8738 <li>Reproducible build</li> 8739 </ul> 8740 {#header_close#} 8741 {#see_also|Compile Variables|Zig Build System|Undefined Behavior#} 8742 {#header_close#} 8743 8744 {#header_open|Single Threaded Builds#} 8745 <p>Zig has a compile option <code>--single-threaded</code> which has the following effects:</p> 8746 <ul> 8747 <li>All {#link|Thread Local Variables#} are treated as {#link|Global Variables#}.</li> 8748 <li>The overhead of {#link|Async Functions#} becomes equivalent to function call overhead.</li> 8749 <li>The {#syntax#}@import("builtin").single_threaded{#endsyntax#} becomes {#syntax#}true{#endsyntax#} 8750 and therefore various userland APIs which read this variable become more efficient. 8751 For example {#syntax#}std.Mutex{#endsyntax#} becomes 8752 an empty data structure and all of its functions become no-ops.</li> 8753 </ul> 8754 {#header_close#} 8755 8756 {#header_open|Undefined Behavior#} 8757 <p> 8758 Zig has many instances of undefined behavior. If undefined behavior is 8759 detected at compile-time, Zig emits a compile error and refuses to continue. 8760 Most undefined behavior that cannot be detected at compile-time can be detected 8761 at runtime. In these cases, Zig has safety checks. Safety checks can be disabled 8762 on a per-block basis with {#link|@setRuntimeSafety#}. The {#link|ReleaseFast#} 8763 and {#link|ReleaseSmall#} build modes disable all safety checks (except where overridden 8764 by {#link|@setRuntimeSafety#}) in order to facilitate optimizations. 8765 </p> 8766 <p> 8767 When a safety check fails, Zig crashes with a stack trace, like this: 8768 </p> 8769 {#code_begin|test_err|reached unreachable code#} 8770 test "safety check" { 8771 unreachable; 8772 } 8773 {#code_end#} 8774 {#header_open|Reaching Unreachable Code#} 8775 <p>At compile-time:</p> 8776 {#code_begin|test_err|reached unreachable code#} 8777 comptime { 8778 assert(false); 8779 } 8780 fn assert(ok: bool) void { 8781 if (!ok) unreachable; // assertion failure 8782 } 8783 {#code_end#} 8784 <p>At runtime:</p> 8785 {#code_begin|exe_err#} 8786 const std = @import("std"); 8787 8788 pub fn main() void { 8789 std.debug.assert(false); 8790 } 8791 {#code_end#} 8792 {#header_close#} 8793 {#header_open|Index out of Bounds#} 8794 <p>At compile-time:</p> 8795 {#code_begin|test_err|index 5 outside array of size 5#} 8796 comptime { 8797 const array: [5]u8 = "hello".*; 8798 const garbage = array[5]; 8799 } 8800 {#code_end#} 8801 <p>At runtime:</p> 8802 {#code_begin|exe_err#} 8803 pub fn main() void { 8804 var x = foo("hello"); 8805 } 8806 8807 fn foo(x: []const u8) u8 { 8808 return x[5]; 8809 } 8810 {#code_end#} 8811 {#header_close#} 8812 {#header_open|Cast Negative Number to Unsigned Integer#} 8813 <p>At compile-time:</p> 8814 {#code_begin|test_err|attempt to cast negative value to unsigned integer#} 8815 comptime { 8816 const value: i32 = -1; 8817 const unsigned = @intCast(u32, value); 8818 } 8819 {#code_end#} 8820 <p>At runtime:</p> 8821 {#code_begin|exe_err#} 8822 const std = @import("std"); 8823 8824 pub fn main() void { 8825 var value: i32 = -1; 8826 var unsigned = @intCast(u32, value); 8827 std.debug.print("value: {}\n", .{unsigned}); 8828 } 8829 {#code_end#} 8830 <p> 8831 To obtain the maximum value of an unsigned integer, use {#syntax#}std.math.maxInt{#endsyntax#}. 8832 </p> 8833 {#header_close#} 8834 {#header_open|Cast Truncates Data#} 8835 <p>At compile-time:</p> 8836 {#code_begin|test_err|cast from 'u16' to 'u8' truncates bits#} 8837 comptime { 8838 const spartan_count: u16 = 300; 8839 const byte = @intCast(u8, spartan_count); 8840 } 8841 {#code_end#} 8842 <p>At runtime:</p> 8843 {#code_begin|exe_err#} 8844 const std = @import("std"); 8845 8846 pub fn main() void { 8847 var spartan_count: u16 = 300; 8848 const byte = @intCast(u8, spartan_count); 8849 std.debug.print("value: {}\n", .{byte}); 8850 } 8851 {#code_end#} 8852 <p> 8853 To truncate bits, use {#link|@truncate#}. 8854 </p> 8855 {#header_close#} 8856 {#header_open|Integer Overflow#} 8857 {#header_open|Default Operations#} 8858 <p>The following operators can cause integer overflow:</p> 8859 <ul> 8860 <li>{#syntax#}+{#endsyntax#} (addition)</li> 8861 <li>{#syntax#}-{#endsyntax#} (subtraction)</li> 8862 <li>{#syntax#}-{#endsyntax#} (negation)</li> 8863 <li>{#syntax#}*{#endsyntax#} (multiplication)</li> 8864 <li>{#syntax#}/{#endsyntax#} (division)</li> 8865 <li>{#link|@divTrunc#} (division)</li> 8866 <li>{#link|@divFloor#} (division)</li> 8867 <li>{#link|@divExact#} (division)</li> 8868 </ul> 8869 <p>Example with addition at compile-time:</p> 8870 {#code_begin|test_err|operation caused overflow#} 8871 comptime { 8872 var byte: u8 = 255; 8873 byte += 1; 8874 } 8875 {#code_end#} 8876 <p>At runtime:</p> 8877 {#code_begin|exe_err#} 8878 const std = @import("std"); 8879 8880 pub fn main() void { 8881 var byte: u8 = 255; 8882 byte += 1; 8883 std.debug.print("value: {}\n", .{byte}); 8884 } 8885 {#code_end#} 8886 {#header_close#} 8887 {#header_open|Standard Library Math Functions#} 8888 <p>These functions provided by the standard library return possible errors.</p> 8889 <ul> 8890 <li>{#syntax#}@import("std").math.add{#endsyntax#}</li> 8891 <li>{#syntax#}@import("std").math.sub{#endsyntax#}</li> 8892 <li>{#syntax#}@import("std").math.mul{#endsyntax#}</li> 8893 <li>{#syntax#}@import("std").math.divTrunc{#endsyntax#}</li> 8894 <li>{#syntax#}@import("std").math.divFloor{#endsyntax#}</li> 8895 <li>{#syntax#}@import("std").math.divExact{#endsyntax#}</li> 8896 <li>{#syntax#}@import("std").math.shl{#endsyntax#}</li> 8897 </ul> 8898 <p>Example of catching an overflow for addition:</p> 8899 {#code_begin|exe_err#} 8900 const math = @import("std").math; 8901 const print = @import("std").debug.print; 8902 pub fn main() !void { 8903 var byte: u8 = 255; 8904 8905 byte = if (math.add(u8, byte, 1)) |result| result else |err| { 8906 print("unable to add one: {s}\n", .{@errorName(err)}); 8907 return err; 8908 }; 8909 8910 print("result: {}\n", .{byte}); 8911 } 8912 {#code_end#} 8913 {#header_close#} 8914 {#header_open|Builtin Overflow Functions#} 8915 <p> 8916 These builtins return a {#syntax#}bool{#endsyntax#} of whether or not overflow 8917 occurred, as well as returning the overflowed bits: 8918 </p> 8919 <ul> 8920 <li>{#link|@addWithOverflow#}</li> 8921 <li>{#link|@subWithOverflow#}</li> 8922 <li>{#link|@mulWithOverflow#}</li> 8923 <li>{#link|@shlWithOverflow#}</li> 8924 </ul> 8925 <p> 8926 Example of {#link|@addWithOverflow#}: 8927 </p> 8928 {#code_begin|exe#} 8929 const print = @import("std").debug.print; 8930 pub fn main() void { 8931 var byte: u8 = 255; 8932 8933 var result: u8 = undefined; 8934 if (@addWithOverflow(u8, byte, 10, &result)) { 8935 print("overflowed result: {}\n", .{result}); 8936 } else { 8937 print("result: {}\n", .{result}); 8938 } 8939 } 8940 {#code_end#} 8941 {#header_close#} 8942 {#header_open|Wrapping Operations#} 8943 <p> 8944 These operations have guaranteed wraparound semantics. 8945 </p> 8946 <ul> 8947 <li>{#syntax#}+%{#endsyntax#} (wraparound addition)</li> 8948 <li>{#syntax#}-%{#endsyntax#} (wraparound subtraction)</li> 8949 <li>{#syntax#}-%{#endsyntax#} (wraparound negation)</li> 8950 <li>{#syntax#}*%{#endsyntax#} (wraparound multiplication)</li> 8951 </ul> 8952 {#code_begin|test#} 8953 const std = @import("std"); 8954 const expect = std.testing.expect; 8955 const minInt = std.math.minInt; 8956 const maxInt = std.math.maxInt; 8957 8958 test "wraparound addition and subtraction" { 8959 const x: i32 = maxInt(i32); 8960 const min_val = x +% 1; 8961 try expect(min_val == minInt(i32)); 8962 const max_val = min_val -% 1; 8963 try expect(max_val == maxInt(i32)); 8964 } 8965 {#code_end#} 8966 {#header_close#} 8967 {#header_close#} 8968 {#header_open|Exact Left Shift Overflow#} 8969 <p>At compile-time:</p> 8970 {#code_begin|test_err|operation caused overflow#} 8971 comptime { 8972 const x = @shlExact(@as(u8, 0b01010101), 2); 8973 } 8974 {#code_end#} 8975 <p>At runtime:</p> 8976 {#code_begin|exe_err#} 8977 const std = @import("std"); 8978 8979 pub fn main() void { 8980 var x: u8 = 0b01010101; 8981 var y = @shlExact(x, 2); 8982 std.debug.print("value: {}\n", .{y}); 8983 } 8984 {#code_end#} 8985 {#header_close#} 8986 {#header_open|Exact Right Shift Overflow#} 8987 <p>At compile-time:</p> 8988 {#code_begin|test_err|exact shift shifted out 1 bits#} 8989 comptime { 8990 const x = @shrExact(@as(u8, 0b10101010), 2); 8991 } 8992 {#code_end#} 8993 <p>At runtime:</p> 8994 {#code_begin|exe_err#} 8995 const std = @import("std"); 8996 8997 pub fn main() void { 8998 var x: u8 = 0b10101010; 8999 var y = @shrExact(x, 2); 9000 std.debug.print("value: {}\n", .{y}); 9001 } 9002 {#code_end#} 9003 {#header_close#} 9004 {#header_open|Division by Zero#} 9005 <p>At compile-time:</p> 9006 {#code_begin|test_err|division by zero#} 9007 comptime { 9008 const a: i32 = 1; 9009 const b: i32 = 0; 9010 const c = a / b; 9011 } 9012 {#code_end#} 9013 <p>At runtime:</p> 9014 {#code_begin|exe_err#} 9015 const std = @import("std"); 9016 9017 pub fn main() void { 9018 var a: u32 = 1; 9019 var b: u32 = 0; 9020 var c = a / b; 9021 std.debug.print("value: {}\n", .{c}); 9022 } 9023 {#code_end#} 9024 {#header_close#} 9025 {#header_open|Remainder Division by Zero#} 9026 <p>At compile-time:</p> 9027 {#code_begin|test_err|division by zero#} 9028 comptime { 9029 const a: i32 = 10; 9030 const b: i32 = 0; 9031 const c = a % b; 9032 } 9033 {#code_end#} 9034 <p>At runtime:</p> 9035 {#code_begin|exe_err#} 9036 const std = @import("std"); 9037 9038 pub fn main() void { 9039 var a: u32 = 10; 9040 var b: u32 = 0; 9041 var c = a % b; 9042 std.debug.print("value: {}\n", .{c}); 9043 } 9044 {#code_end#} 9045 {#header_close#} 9046 {#header_open|Exact Division Remainder#} 9047 <p>At compile-time:</p> 9048 {#code_begin|test_err|exact division had a remainder#} 9049 comptime { 9050 const a: u32 = 10; 9051 const b: u32 = 3; 9052 const c = @divExact(a, b); 9053 } 9054 {#code_end#} 9055 <p>At runtime:</p> 9056 {#code_begin|exe_err#} 9057 const std = @import("std"); 9058 9059 pub fn main() void { 9060 var a: u32 = 10; 9061 var b: u32 = 3; 9062 var c = @divExact(a, b); 9063 std.debug.print("value: {}\n", .{c}); 9064 } 9065 {#code_end#} 9066 {#header_close#} 9067 {#header_open|Attempt to Unwrap Null#} 9068 <p>At compile-time:</p> 9069 {#code_begin|test_err|unable to unwrap null#} 9070 comptime { 9071 const optional_number: ?i32 = null; 9072 const number = optional_number.?; 9073 } 9074 {#code_end#} 9075 <p>At runtime:</p> 9076 {#code_begin|exe_err#} 9077 const std = @import("std"); 9078 9079 pub fn main() void { 9080 var optional_number: ?i32 = null; 9081 var number = optional_number.?; 9082 std.debug.print("value: {}\n", .{number}); 9083 } 9084 {#code_end#} 9085 <p>One way to avoid this crash is to test for null instead of assuming non-null, with 9086 the {#syntax#}if{#endsyntax#} expression:</p> 9087 {#code_begin|exe|test#} 9088 const print = @import("std").debug.print; 9089 pub fn main() void { 9090 const optional_number: ?i32 = null; 9091 9092 if (optional_number) |number| { 9093 print("got number: {}\n", .{number}); 9094 } else { 9095 print("it's null\n", .{}); 9096 } 9097 } 9098 {#code_end#} 9099 {#see_also|Optionals#} 9100 {#header_close#} 9101 {#header_open|Attempt to Unwrap Error#} 9102 <p>At compile-time:</p> 9103 {#code_begin|test_err|caught unexpected error 'UnableToReturnNumber'#} 9104 comptime { 9105 const number = getNumberOrFail() catch unreachable; 9106 } 9107 9108 fn getNumberOrFail() !i32 { 9109 return error.UnableToReturnNumber; 9110 } 9111 {#code_end#} 9112 <p>At runtime:</p> 9113 {#code_begin|exe_err#} 9114 const std = @import("std"); 9115 9116 pub fn main() void { 9117 const number = getNumberOrFail() catch unreachable; 9118 std.debug.print("value: {}\n", .{number}); 9119 } 9120 9121 fn getNumberOrFail() !i32 { 9122 return error.UnableToReturnNumber; 9123 } 9124 {#code_end#} 9125 <p>One way to avoid this crash is to test for an error instead of assuming a successful result, with 9126 the {#syntax#}if{#endsyntax#} expression:</p> 9127 {#code_begin|exe#} 9128 const print = @import("std").debug.print; 9129 9130 pub fn main() void { 9131 const result = getNumberOrFail(); 9132 9133 if (result) |number| { 9134 print("got number: {}\n", .{number}); 9135 } else |err| { 9136 print("got error: {s}\n", .{@errorName(err)}); 9137 } 9138 } 9139 9140 fn getNumberOrFail() !i32 { 9141 return error.UnableToReturnNumber; 9142 } 9143 {#code_end#} 9144 {#see_also|Errors#} 9145 {#header_close#} 9146 {#header_open|Invalid Error Code#} 9147 <p>At compile-time:</p> 9148 {#code_begin|test_err|integer value 11 represents no error#} 9149 comptime { 9150 const err = error.AnError; 9151 const number = @errorToInt(err) + 10; 9152 const invalid_err = @intToError(number); 9153 } 9154 {#code_end#} 9155 <p>At runtime:</p> 9156 {#code_begin|exe_err#} 9157 const std = @import("std"); 9158 9159 pub fn main() void { 9160 var err = error.AnError; 9161 var number = @errorToInt(err) + 500; 9162 var invalid_err = @intToError(number); 9163 std.debug.print("value: {}\n", .{number}); 9164 } 9165 {#code_end#} 9166 {#header_close#} 9167 {#header_open|Invalid Enum Cast#} 9168 <p>At compile-time:</p> 9169 {#code_begin|test_err|has no tag matching integer value 3#} 9170 const Foo = enum { 9171 a, 9172 b, 9173 c, 9174 }; 9175 comptime { 9176 const a: u2 = 3; 9177 const b = @intToEnum(Foo, a); 9178 } 9179 {#code_end#} 9180 <p>At runtime:</p> 9181 {#code_begin|exe_err#} 9182 const std = @import("std"); 9183 9184 const Foo = enum { 9185 a, 9186 b, 9187 c, 9188 }; 9189 9190 pub fn main() void { 9191 var a: u2 = 3; 9192 var b = @intToEnum(Foo, a); 9193 std.debug.print("value: {s}\n", .{@tagName(b)}); 9194 } 9195 {#code_end#} 9196 {#header_close#} 9197 9198 {#header_open|Invalid Error Set Cast#} 9199 <p>At compile-time:</p> 9200 {#code_begin|test_err|error.B not a member of error set 'Set2'#} 9201 const Set1 = error{ 9202 A, 9203 B, 9204 }; 9205 const Set2 = error{ 9206 A, 9207 C, 9208 }; 9209 comptime { 9210 _ = @errSetCast(Set2, Set1.B); 9211 } 9212 {#code_end#} 9213 <p>At runtime:</p> 9214 {#code_begin|exe_err#} 9215 const std = @import("std"); 9216 9217 const Set1 = error{ 9218 A, 9219 B, 9220 }; 9221 const Set2 = error{ 9222 A, 9223 C, 9224 }; 9225 pub fn main() void { 9226 foo(Set1.B); 9227 } 9228 fn foo(set1: Set1) void { 9229 const x = @errSetCast(Set2, set1); 9230 std.debug.print("value: {}\n", .{x}); 9231 } 9232 {#code_end#} 9233 {#header_close#} 9234 9235 {#header_open|Incorrect Pointer Alignment#} 9236 <p>At compile-time:</p> 9237 {#code_begin|test_err|pointer address 0x1 is not aligned to 4 bytes#} 9238 comptime { 9239 const ptr = @intToPtr(*align(1) i32, 0x1); 9240 const aligned = @alignCast(4, ptr); 9241 } 9242 {#code_end#} 9243 <p>At runtime:</p> 9244 {#code_begin|exe_err#} 9245 const mem = @import("std").mem; 9246 pub fn main() !void { 9247 var array align(4) = [_]u32{ 0x11111111, 0x11111111 }; 9248 const bytes = mem.sliceAsBytes(array[0..]); 9249 if (foo(bytes) != 0x11111111) return error.Wrong; 9250 } 9251 fn foo(bytes: []u8) u32 { 9252 const slice4 = bytes[1..5]; 9253 const int_slice = mem.bytesAsSlice(u32, @alignCast(4, slice4)); 9254 return int_slice[0]; 9255 } 9256 {#code_end#} 9257 {#header_close#} 9258 {#header_open|Wrong Union Field Access#} 9259 <p>At compile-time:</p> 9260 {#code_begin|test_err|accessing union field 'float' while field 'int' is set#} 9261 comptime { 9262 var f = Foo{ .int = 42 }; 9263 f.float = 12.34; 9264 } 9265 9266 const Foo = union { 9267 float: f32, 9268 int: u32, 9269 }; 9270 {#code_end#} 9271 <p>At runtime:</p> 9272 {#code_begin|exe_err#} 9273 const std = @import("std"); 9274 9275 const Foo = union { 9276 float: f32, 9277 int: u32, 9278 }; 9279 9280 pub fn main() void { 9281 var f = Foo{ .int = 42 }; 9282 bar(&f); 9283 } 9284 9285 fn bar(f: *Foo) void { 9286 f.float = 12.34; 9287 std.debug.print("value: {}\n", .{f.float}); 9288 } 9289 {#code_end#} 9290 <p> 9291 This safety is not available for {#syntax#}extern{#endsyntax#} or {#syntax#}packed{#endsyntax#} unions. 9292 </p> 9293 <p> 9294 To change the active field of a union, assign the entire union, like this: 9295 </p> 9296 {#code_begin|exe#} 9297 const std = @import("std"); 9298 9299 const Foo = union { 9300 float: f32, 9301 int: u32, 9302 }; 9303 9304 pub fn main() void { 9305 var f = Foo{ .int = 42 }; 9306 bar(&f); 9307 } 9308 9309 fn bar(f: *Foo) void { 9310 f.* = Foo{ .float = 12.34 }; 9311 std.debug.print("value: {}\n", .{f.float}); 9312 } 9313 {#code_end#} 9314 <p> 9315 To change the active field of a union when a meaningful value for the field is not known, 9316 use {#link|undefined#}, like this: 9317 </p> 9318 {#code_begin|exe#} 9319 const std = @import("std"); 9320 9321 const Foo = union { 9322 float: f32, 9323 int: u32, 9324 }; 9325 9326 pub fn main() void { 9327 var f = Foo{ .int = 42 }; 9328 f = Foo{ .float = undefined }; 9329 bar(&f); 9330 std.debug.print("value: {}\n", .{f.float}); 9331 } 9332 9333 fn bar(f: *Foo) void { 9334 f.float = 12.34; 9335 } 9336 {#code_end#} 9337 {#see_also|union|extern union#} 9338 {#header_close#} 9339 9340 {#header_open|Out of Bounds Float to Integer Cast#} 9341 <p>TODO</p> 9342 {#header_close#} 9343 9344 {#header_open|Pointer Cast Invalid Null#} 9345 <p> 9346 This happens when casting a pointer with the address 0 to a pointer which may not have the address 0. 9347 For example, {#link|C Pointers#}, {#link|Optional Pointers#}, and {#link|allowzero#} pointers 9348 allow address zero, but normal {#link|Pointers#} do not. 9349 </p> 9350 <p>At compile-time:</p> 9351 {#code_begin|test_err|null pointer casted to type#} 9352 comptime { 9353 const opt_ptr: ?*i32 = null; 9354 const ptr = @ptrCast(*i32, opt_ptr); 9355 } 9356 {#code_end#} 9357 <p>At runtime:</p> 9358 {#code_begin|exe_err#} 9359 pub fn main() void { 9360 var opt_ptr: ?*i32 = null; 9361 var ptr = @ptrCast(*i32, opt_ptr); 9362 } 9363 {#code_end#} 9364 {#header_close#} 9365 9366 {#header_close#} 9367 {#header_open|Memory#} 9368 <p> 9369 The Zig language performs no memory management on behalf of the programmer. This is 9370 why Zig has no runtime, and why Zig code works seamlessly in so many environments, 9371 including real-time software, operating system kernels, embedded devices, and 9372 low latency servers. As a consequence, Zig programmers must always be able to answer 9373 the question: 9374 </p> 9375 <p>{#link|Where are the bytes?#}</p> 9376 <p> 9377 Like Zig, the C programming language has manual memory management. However, unlike Zig, 9378 C has a default allocator - <code>malloc</code>, <code>realloc</code>, and <code>free</code>. 9379 When linking against libc, Zig exposes this allocator with {#syntax#}std.heap.c_allocator{#endsyntax#}. 9380 However, by convention, there is no default allocator in Zig. Instead, functions which need to 9381 allocate accept an {#syntax#}*Allocator{#endsyntax#} parameter. Likewise, data structures such as 9382 {#syntax#}std.ArrayList{#endsyntax#} accept an {#syntax#}*Allocator{#endsyntax#} parameter in 9383 their initialization functions: 9384 </p> 9385 {#code_begin|test|allocator#} 9386 const std = @import("std"); 9387 const Allocator = std.mem.Allocator; 9388 const expect = std.testing.expect; 9389 9390 test "using an allocator" { 9391 var buffer: [100]u8 = undefined; 9392 const allocator = &std.heap.FixedBufferAllocator.init(&buffer).allocator; 9393 const result = try concat(allocator, "foo", "bar"); 9394 try expect(std.mem.eql(u8, "foobar", result)); 9395 } 9396 9397 fn concat(allocator: *Allocator, a: []const u8, b: []const u8) ![]u8 { 9398 const result = try allocator.alloc(u8, a.len + b.len); 9399 std.mem.copy(u8, result, a); 9400 std.mem.copy(u8, result[a.len..], b); 9401 return result; 9402 } 9403 {#code_end#} 9404 <p> 9405 In the above example, 100 bytes of stack memory are used to initialize a 9406 {#syntax#}FixedBufferAllocator{#endsyntax#}, which is then passed to a function. 9407 As a convenience there is a global {#syntax#}FixedBufferAllocator{#endsyntax#} 9408 available for quick tests at {#syntax#}std.testing.allocator{#endsyntax#}, 9409 which will also do perform basic leak detection. 9410 </p> 9411 <p> 9412 Zig has a general purpose allocator available to be imported 9413 with {#syntax#}std.heap.GeneralPurposeAllocator{#endsyntax#}. However, it is still recommended to 9414 follow the {#link|Choosing an Allocator#} guide. 9415 </p> 9416 9417 {#header_open|Choosing an Allocator#} 9418 <p>What allocator to use depends on a number of factors. Here is a flow chart to help you decide: 9419 </p> 9420 <ol> 9421 <li> 9422 Are you making a library? In this case, best to accept an {#syntax#}*Allocator{#endsyntax#} 9423 as a parameter and allow your library's users to decide what allocator to use. 9424 </li> 9425 <li>Are you linking libc? In this case, {#syntax#}std.heap.c_allocator{#endsyntax#} is likely 9426 the right choice, at least for your main allocator.</li> 9427 <li> 9428 Is the maximum number of bytes that you will need bounded by a number known at 9429 {#link|comptime#}? In this case, use {#syntax#}std.heap.FixedBufferAllocator{#endsyntax#} or 9430 {#syntax#}std.heap.ThreadSafeFixedBufferAllocator{#endsyntax#} depending on whether you need 9431 thread-safety or not. 9432 </li> 9433 <li> 9434 Is your program a command line application which runs from start to end without any fundamental 9435 cyclical pattern (such as a video game main loop, or a web server request handler), 9436 such that it would make sense to free everything at once at the end? 9437 In this case, it is recommended to follow this pattern: 9438 {#code_begin|exe|cli_allocation#} 9439 const std = @import("std"); 9440 9441 pub fn main() !void { 9442 var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); 9443 defer arena.deinit(); 9444 9445 const allocator = &arena.allocator; 9446 9447 const ptr = try allocator.create(i32); 9448 std.debug.print("ptr={*}\n", .{ptr}); 9449 } 9450 {#code_end#} 9451 When using this kind of allocator, there is no need to free anything manually. Everything 9452 gets freed at once with the call to {#syntax#}arena.deinit(){#endsyntax#}. 9453 </li> 9454 <li> 9455 Are the allocations part of a cyclical pattern such as a video game main loop, or a web 9456 server request handler? If the allocations can all be freed at once, at the end of the cycle, 9457 for example once the video game frame has been fully rendered, or the web server request has 9458 been served, then {#syntax#}std.heap.ArenaAllocator{#endsyntax#} is a great candidate. As 9459 demonstrated in the previous bullet point, this allows you to free entire arenas at once. 9460 Note also that if an upper bound of memory can be established, then 9461 {#syntax#}std.heap.FixedBufferAllocator{#endsyntax#} can be used as a further optimization. 9462 </li> 9463 <li> 9464 Are you writing a test, and you want to make sure {#syntax#}error.OutOfMemory{#endsyntax#} 9465 is handled correctly? In this case, use {#syntax#}std.testing.FailingAllocator{#endsyntax#}. 9466 </li> 9467 <li> 9468 Are you writing a test? In this case, use {#syntax#}std.testing.allocator{#endsyntax#}. 9469 </li> 9470 <li> 9471 Finally, if none of the above apply, you need a general purpose allocator. 9472 Zig's general purpose allocator is available as a function that takes a {#link|comptime#} 9473 {#link|struct#} of configuration options and returns a type. 9474 Generally, you will set up one {#syntax#}std.heap.GeneralPurposeAllocator{#endsyntax#} in 9475 your main function, and then pass it or sub-allocators around to various parts of your 9476 application. 9477 </li> 9478 <li> 9479 You can also consider {#link|Implementing an Allocator#}. 9480 </li> 9481 </ol> 9482 {#header_close#} 9483 9484 {#header_open|Where are the bytes?#} 9485 <p>String literals such as {#syntax#}"foo"{#endsyntax#} are in the global constant data section. 9486 This is why it is an error to pass a string literal to a mutable slice, like this: 9487 </p> 9488 {#code_begin|test_err|expected type '[]u8'#} 9489 fn foo(s: []u8) void {} 9490 9491 test "string literal to mutable slice" { 9492 foo("hello"); 9493 } 9494 {#code_end#} 9495 <p>However if you make the slice constant, then it works:</p> 9496 {#code_begin|test|strlit#} 9497 fn foo(s: []const u8) void {} 9498 9499 test "string literal to constant slice" { 9500 foo("hello"); 9501 } 9502 {#code_end#} 9503 <p> 9504 Just like string literals, {#syntax#}const{#endsyntax#} declarations, when the value is known at {#link|comptime#}, 9505 are stored in the global constant data section. Also {#link|Compile Time Variables#} are stored 9506 in the global constant data section. 9507 </p> 9508 <p> 9509 {#syntax#}var{#endsyntax#} declarations inside functions are stored in the function's stack frame. Once a function returns, 9510 any {#link|Pointers#} to variables in the function's stack frame become invalid references, and 9511 dereferencing them becomes unchecked {#link|Undefined Behavior#}. 9512 </p> 9513 <p> 9514 {#syntax#}var{#endsyntax#} declarations at the top level or in {#link|struct#} declarations are stored in the global 9515 data section. 9516 </p> 9517 <p> 9518 The location of memory allocated with {#syntax#}allocator.alloc{#endsyntax#} or 9519 {#syntax#}allocator.create{#endsyntax#} is determined by the allocator's implementation. 9520 </p> 9521 <p>TODO: thread local variables</p> 9522 {#header_close#} 9523 9524 {#header_open|Implementing an Allocator#} 9525 <p>Zig programmers can implement their own allocators by fulfilling the Allocator interface. 9526 In order to do this one must read carefully the documentation comments in std/mem.zig and 9527 then supply a {#syntax#}reallocFn{#endsyntax#} and a {#syntax#}shrinkFn{#endsyntax#}. 9528 </p> 9529 <p> 9530 There are many example allocators to look at for inspiration. Look at std/heap.zig and 9531 at this 9532 <a href="https://github.com/andrewrk/zig-general-purpose-allocator/">work-in-progress general purpose allocator</a>. 9533 TODO: once <a href="https://github.com/ziglang/zig/issues/21">#21</a> is done, link to the docs 9534 here. 9535 </p> 9536 {#header_close#} 9537 9538 {#header_open|Heap Allocation Failure#} 9539 <p> 9540 Many programming languages choose to handle the possibility of heap allocation failure by 9541 unconditionally crashing. By convention, Zig programmers do not consider this to be a 9542 satisfactory solution. Instead, {#syntax#}error.OutOfMemory{#endsyntax#} represents 9543 heap allocation failure, and Zig libraries return this error code whenever heap allocation 9544 failure prevented an operation from completing successfully. 9545 </p> 9546 <p> 9547 Some have argued that because some operating systems such as Linux have memory overcommit enabled by 9548 default, it is pointless to handle heap allocation failure. There are many problems with this reasoning: 9549 </p> 9550 <ul> 9551 <li>Only some operating systems have an overcommit feature. 9552 <ul> 9553 <li>Linux has it enabled by default, but it is configurable.</li> 9554 <li>Windows does not overcommit.</li> 9555 <li>Embedded systems do not have overcommit.</li> 9556 <li>Hobby operating systems may or may not have overcommit.</li> 9557 </ul> 9558 </li> 9559 <li> 9560 For real-time systems, not only is there no overcommit, but typically the maximum amount 9561 of memory per application is determined ahead of time. 9562 </li> 9563 <li> 9564 When writing a library, one of the main goals is code reuse. By making code handle 9565 allocation failure correctly, a library becomes eligible to be reused in 9566 more contexts. 9567 </li> 9568 <li> 9569 Although some software has grown to depend on overcommit being enabled, its existence 9570 is the source of countless user experience disasters. When a system with overcommit enabled, 9571 such as Linux on default settings, comes close to memory exhaustion, the system locks up 9572 and becomes unusable. At this point, the OOM Killer selects an application to kill 9573 based on heuristics. This non-deterministic decision often results in an important process 9574 being killed, and often fails to return the system back to working order. 9575 </li> 9576 </ul> 9577 {#header_close#} 9578 9579 {#header_open|Recursion#} 9580 <p> 9581 Recursion is a fundamental tool in modeling software. However it has an often-overlooked problem: 9582 unbounded memory allocation. 9583 </p> 9584 <p> 9585 Recursion is an area of active experimentation in Zig and so the documentation here is not final. 9586 You can read a 9587 <a href="https://ziglang.org/download/0.3.0/release-notes.html#recursion">summary of recursion status in the 0.3.0 release notes</a>. 9588 </p> 9589 <p> 9590 The short summary is that currently recursion works normally as you would expect. Although Zig code 9591 is not yet protected from stack overflow, it is planned that a future version of Zig will provide 9592 such protection, with some degree of cooperation from Zig code required. 9593 </p> 9594 {#header_close#} 9595 9596 {#header_open|Lifetime and Ownership#} 9597 <p> 9598 It is the Zig programmer's responsibility to ensure that a {#link|pointer|Pointers#} is not 9599 accessed when the memory pointed to is no longer available. Note that a {#link|slice|Slices#} 9600 is a form of pointer, in that it references other memory. 9601 </p> 9602 <p> 9603 In order to prevent bugs, there are some helpful conventions to follow when dealing with pointers. 9604 In general, when a function returns a pointer, the documentation for the function should explain 9605 who "owns" the pointer. This concept helps the programmer decide when it is appropriate, if ever, 9606 to free the pointer. 9607 </p> 9608 <p> 9609 For example, the function's documentation may say "caller owns the returned memory", in which case 9610 the code that calls the function must have a plan for when to free that memory. Probably in this situation, 9611 the function will accept an {#syntax#}*Allocator{#endsyntax#} parameter. 9612 </p> 9613 <p> 9614 Sometimes the lifetime of a pointer may be more complicated. For example, the 9615 {#syntax#}std.ArrayList(T).items{#endsyntax#} slice has a lifetime that remains 9616 valid until the next time the list is resized, such as by appending new elements. 9617 </p> 9618 <p> 9619 The API documentation for functions and data structures should take great care to explain 9620 the ownership and lifetime semantics of pointers. Ownership determines whose responsibility it 9621 is to free the memory referenced by the pointer, and lifetime determines the point at which 9622 the memory becomes inaccessible (lest {#link|Undefined Behavior#} occur). 9623 </p> 9624 {#header_close#} 9625 9626 {#header_close#} 9627 {#header_open|Compile Variables#} 9628 <p> 9629 Compile variables are accessible by importing the {#syntax#}"builtin"{#endsyntax#} package, 9630 which the compiler makes available to every Zig source file. It contains 9631 compile-time constants such as the current target, endianness, and release mode. 9632 </p> 9633 {#code_begin|syntax#} 9634 const builtin = @import("builtin"); 9635 const separator = if (builtin.os.tag == builtin.Os.windows) '\\' else '/'; 9636 {#code_end#} 9637 <p> 9638 Example of what is imported with {#syntax#}@import("builtin"){#endsyntax#}: 9639 </p> 9640 {#builtin#} 9641 {#see_also|Build Mode#} 9642 {#header_close#} 9643 {#header_open|Root Source File#} 9644 <p>TODO: explain how root source file finds other files</p> 9645 <p>TODO: pub fn main</p> 9646 <p>TODO: pub fn panic</p> 9647 <p>TODO: if linking with libc you can use export fn main</p> 9648 <p>TODO: order independent top level declarations</p> 9649 <p>TODO: lazy analysis</p> 9650 <p>TODO: using comptime { _ = @import() }</p> 9651 {#header_close#} 9652 {#header_open|Zig Test#} 9653 <p> 9654 <code>zig test</code> is a tool that can be used to quickly build and run Zig code 9655 to make sure behavior meets expectations. {#syntax#}@import("builtin").is_test{#endsyntax#} 9656 is available for code to detect whether the current build is a test build. 9657 </p> 9658 {#code_begin|test|detect_test#} 9659 const std = @import("std"); 9660 const builtin = @import("builtin"); 9661 const expect = std.testing.expect; 9662 9663 test "builtin.is_test" { 9664 try expect(builtin.is_test); 9665 } 9666 {#code_end#} 9667 <p> 9668 Zig has lazy top level declaration analysis, which means that if a function is not called, 9669 or otherwise used, it is not analyzed. This means that there may be an undiscovered 9670 compile error in a function because it is never called. 9671 </p> 9672 {#code_begin|test|unused_fn#} 9673 fn unused() i32 { 9674 return "wrong return type"; 9675 } 9676 test "unused function" { } 9677 {#code_end#} 9678 <p> 9679 Note that, while in {#link|Debug#} and {#link|ReleaseSafe#} modes, {#link|unreachable#} emits a 9680 call to {#link|@panic#}, in {#link|ReleaseFast#} and {#link|ReleaseSmall#} modes, it is really 9681 undefined behavior. The implementation of {#syntax#}std.debug.assert{#endsyntax#} is as 9682 simple as: 9683 </p> 9684 {#code_begin|syntax#} 9685 pub fn assert(ok: bool) void { 9686 if (!ok) unreachable; 9687 } 9688 {#code_end#} 9689 <p> 9690 This means that when testing in ReleaseFast or ReleaseSmall mode, {#syntax#}assert{#endsyntax#} 9691 is not sufficient to check the result of a computation: 9692 </p> 9693 {#code_begin|syntax#} 9694 const std = @import("std"); 9695 const assert = std.debug.assert; 9696 9697 test "assert in release fast mode" { 9698 assert(false); 9699 } 9700 {#code_end#} 9701 <p> 9702 When compiling this test in {#link|ReleaseFast#} mode, it invokes unchecked 9703 {#link|Undefined Behavior#}. Since that could do anything, this documentation 9704 cannot show you the output. 9705 </p> 9706 <p> 9707 Better practice for checking the output when testing is to use {#syntax#}std.testing.expect{#endsyntax#}: 9708 </p> 9709 {#code_begin|test_err|test "expect in release fast mode"... FAIL (TestUnexpectedResult)#} 9710 {#code_release_fast#} 9711 const std = @import("std"); 9712 const expect = std.testing.expect; 9713 9714 test "expect in release fast mode" { 9715 try expect(false); 9716 } 9717 {#code_end#} 9718 <p>See the rest of the {#syntax#}std.testing{#endsyntax#} namespace for more available functions.</p> 9719 <p> 9720 <code>zig test</code> has a few command line parameters which affect the compilation. See 9721 <code>zig --help</code> for a full list. The most interesting one is <code>--test-filter [text]</code>. 9722 This makes the test build only include tests whose name contains the supplied filter text. 9723 Again, thanks to lazy analysis, this can allow you to narrow a build to only a few functions in 9724 isolation. 9725 </p> 9726 {#header_close#} 9727 9728 {#header_open|Zig Build System#} 9729 <p> 9730 The Zig Build System provides a cross-platform, dependency-free way to declare 9731 the logic required to build a project. With this system, the logic to build 9732 a project is written in a build.zig file, using the Zig Build System API to 9733 declare and configure build artifacts and other tasks. 9734 </p> 9735 <p> 9736 Some examples of tasks the build system can help with: 9737 </p> 9738 <ul> 9739 <li>Creating build artifacts by executing the Zig compiler. This includes 9740 building Zig source code as well as C and C++ source code.</li> 9741 <li>Capturing user-configured options and using those options to configure 9742 the build.</li> 9743 <li>Surfacing build configuration as {#link|comptime#} values by providing a 9744 file that can be {#link|imported|@import#} by Zig code.</li> 9745 <li>Caching build artifacts to avoid unnecessarily repeating steps.</li> 9746 <li>Executing build artifacts or system-installed tools.</li> 9747 <li>Running tests and verifying the output of executing a build artifact matches 9748 the expected value.</li> 9749 <li>Running <code>zig fmt</code> on a codebase or a subset of it.</li> 9750 <li>Custom tasks.</li> 9751 </ul> 9752 <p> 9753 To use the build system, run <code class="shell">zig build --help</code> 9754 to see a command-line usage help menu. This will include project-specific 9755 options that were declared in the build.zig script. 9756 </p> 9757 9758 {#header_open|Building an Executable#} 9759 <p>This <code>build.zig</code> file is automatically generated 9760 by <code>zig init-exe</code>.</p> 9761 {#code_begin|syntax|build#} 9762 const Builder = @import("std").build.Builder; 9763 9764 pub fn build(b: *Builder) void { 9765 // Standard target options allows the person running `zig build` to choose 9766 // what target to build for. Here we do not override the defaults, which 9767 // means any target is allowed, and the default is native. Other options 9768 // for restricting supported target set are available. 9769 const target = b.standardTargetOptions(.{}); 9770 9771 // Standard release options allow the person running `zig build` to select 9772 // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. 9773 const mode = b.standardReleaseOptions(); 9774 9775 const exe = b.addExecutable("example", "src/main.zig"); 9776 exe.setTarget(target); 9777 exe.setBuildMode(mode); 9778 exe.install(); 9779 9780 const run_cmd = exe.run(); 9781 run_cmd.step.dependOn(b.getInstallStep()); 9782 if (b.args) |args| { 9783 run_cmd.addArgs(args); 9784 } 9785 9786 const run_step = b.step("run", "Run the app"); 9787 run_step.dependOn(&run_cmd.step); 9788 } 9789 {#code_end#} 9790 {#header_close#} 9791 9792 {#header_open|Building a Library#} 9793 <p>This <code>build.zig</code> file is automatically generated 9794 by <code>zig init-lib</code>.</p> 9795 {#code_begin|syntax|build#} 9796 const Builder = @import("std").build.Builder; 9797 9798 pub fn build(b: *Builder) void { 9799 const mode = b.standardReleaseOptions(); 9800 const lib = b.addStaticLibrary("example", "src/main.zig"); 9801 lib.setBuildMode(mode); 9802 lib.install(); 9803 9804 var main_tests = b.addTest("src/main.zig"); 9805 main_tests.setBuildMode(mode); 9806 9807 const test_step = b.step("test", "Run library tests"); 9808 test_step.dependOn(&main_tests.step); 9809 } 9810 {#code_end#} 9811 {#header_close#} 9812 9813 {#header_open|Compiling C Source Code#} 9814 <pre>{#syntax#} 9815 lib.addCSourceFile("src/lib.c", &[_][]const u8{ 9816 "-Wall", 9817 "-Wextra", 9818 "-Werror", 9819 }); 9820 {#endsyntax#}</pre> 9821 {#header_close#} 9822 9823 {#header_close#} 9824 {#header_open|C#} 9825 <p> 9826 Although Zig is independent of C, and, unlike most other languages, does not depend on libc, 9827 Zig acknowledges the importance of interacting with existing C code. 9828 </p> 9829 <p> 9830 There are a few ways that Zig facilitates C interop. 9831 </p> 9832 {#header_open|C Type Primitives#} 9833 <p> 9834 These have guaranteed C ABI compatibility and can be used like any other type. 9835 </p> 9836 <ul> 9837 <li>{#syntax#}c_short{#endsyntax#}</li> 9838 <li>{#syntax#}c_ushort{#endsyntax#}</li> 9839 <li>{#syntax#}c_int{#endsyntax#}</li> 9840 <li>{#syntax#}c_uint{#endsyntax#}</li> 9841 <li>{#syntax#}c_long{#endsyntax#}</li> 9842 <li>{#syntax#}c_ulong{#endsyntax#}</li> 9843 <li>{#syntax#}c_longlong{#endsyntax#}</li> 9844 <li>{#syntax#}c_ulonglong{#endsyntax#}</li> 9845 <li>{#syntax#}c_longdouble{#endsyntax#}</li> 9846 <li>{#syntax#}c_void{#endsyntax#}</li> 9847 </ul> 9848 {#see_also|Primitive Types#} 9849 {#header_close#} 9850 9851 {#header_open|Import from C Header File#} 9852 <p> 9853 The {#syntax#}@cImport{#endsyntax#} builtin function can be used 9854 to directly import symbols from .h files: 9855 </p> 9856 {#code_begin|exe#} 9857 {#link_libc#} 9858 const c = @cImport({ 9859 // See https://github.com/ziglang/zig/issues/515 9860 @cDefine("_NO_CRT_STDIO_INLINE", "1"); 9861 @cInclude("stdio.h"); 9862 }); 9863 pub fn main() void { 9864 _ = c.printf("hello\n"); 9865 } 9866 {#code_end#} 9867 <p> 9868 The {#syntax#}@cImport{#endsyntax#} function takes an expression as a parameter. 9869 This expression is evaluated at compile-time and is used to control 9870 preprocessor directives and include multiple .h files: 9871 </p> 9872 {#code_begin|syntax#} 9873 const builtin = @import("builtin"); 9874 9875 const c = @cImport({ 9876 @cDefine("NDEBUG", builtin.mode == .ReleaseFast); 9877 if (something) { 9878 @cDefine("_GNU_SOURCE", {}); 9879 } 9880 @cInclude("stdlib.h"); 9881 if (something) { 9882 @cUndef("_GNU_SOURCE"); 9883 } 9884 @cInclude("soundio.h"); 9885 }); 9886 {#code_end#} 9887 {#see_also|@cImport|@cInclude|@cDefine|@cUndef|@import#} 9888 {#header_close#} 9889 9890 {#header_open|C Pointers#} 9891 <p> 9892 This type is to be avoided whenever possible. The only valid reason for using a C pointer is in 9893 auto-generated code from translating C code. 9894 </p> 9895 <p> 9896 When importing C header files, it is ambiguous whether pointers should be translated as 9897 single-item pointers ({#syntax#}*T{#endsyntax#}) or many-item pointers ({#syntax#}[*]T{#endsyntax#}). 9898 C pointers are a compromise so that Zig code can utilize translated header files directly. 9899 </p> 9900 <p>{#syntax#}[*c]T{#endsyntax#} - C pointer.</p> 9901 <ul> 9902 <li>Supports all the syntax of the other two pointer types.</li> 9903 <li>Coerces to other pointer types, as well as {#link|Optional Pointers#}. 9904 When a C pointer is coerced to a non-optional pointer, safety-checked 9905 {#link|Undefined Behavior#} occurs if the address is 0. 9906 </li> 9907 <li>Allows address 0. On non-freestanding targets, dereferencing address 0 is safety-checked 9908 {#link|Undefined Behavior#}. Optional C pointers introduce another bit to keep track of 9909 null, just like {#syntax#}?usize{#endsyntax#}. Note that creating an optional C pointer 9910 is unnecessary as one can use normal {#link|Optional Pointers#}. 9911 </li> 9912 <li>Supports {#link|Type Coercion#} to and from integers.</li> 9913 <li>Supports comparison with integers.</li> 9914 <li>Does not support Zig-only pointer attributes such as alignment. Use normal {#link|Pointers#} 9915 please!</li> 9916 </ul> 9917 <p>When a C pointer is pointing to a single struct (not an array), dereference the C pointer to 9918 access to the struct's fields or member data. That syntax looks like 9919 this: </p> 9920 <p>{#syntax#}ptr_to_struct.*.struct_member{#endsyntax#}</p> 9921 <p>This is comparable to doing {#syntax#}->{#endsyntax#} in C.</p> 9922 <p> When a C pointer is pointing to an array of structs, the syntax reverts to this:</p> 9923 <p>{#syntax#}ptr_to_struct_array[index].struct_member{#endsyntax#}</p> 9924 {#header_close#} 9925 9926 {#header_open|Exporting a C Library#} 9927 <p> 9928 One of the primary use cases for Zig is exporting a library with the C ABI for other programming languages 9929 to call into. The {#syntax#}export{#endsyntax#} keyword in front of functions, variables, and types causes them to 9930 be part of the library API: 9931 </p> 9932 <p class="file">mathtest.zig</p> 9933 {#code_begin|syntax#} 9934 export fn add(a: i32, b: i32) i32 { 9935 return a + b; 9936 } 9937 {#code_end#} 9938 <p>To make a static library:</p> 9939 <pre><code class="shell">$ zig build-lib mathtest.zig 9940 </code></pre> 9941 <p>To make a shared library:</p> 9942 <pre><code class="shell">$ zig build-lib mathtest.zig -dynamic 9943 </code></pre> 9944 <p>Here is an example with the {#link|Zig Build System#}:</p> 9945 <p class="file">test.c</p> 9946 <pre><code class="cpp">// This header is generated by zig from mathtest.zig 9947 #include "mathtest.h" 9948 #include <stdio.h> 9949 9950 int main(int argc, char **argv) { 9951 int32_t result = add(42, 1337); 9952 printf("%d\n", result); 9953 return 0; 9954 }</code></pre> 9955 <p class="file">build.zig</p> 9956 {#code_begin|syntax#} 9957 const Builder = @import("std").build.Builder; 9958 9959 pub fn build(b: *Builder) void { 9960 const lib = b.addSharedLibrary("mathtest", "mathtest.zig", b.version(1, 0, 0)); 9961 9962 const exe = b.addExecutable("test", null); 9963 exe.addCSourceFile("test.c", &[_][]const u8{"-std=c99"}); 9964 exe.linkLibrary(lib); 9965 exe.linkSystemLibrary("c"); 9966 9967 b.default_step.dependOn(&exe.step); 9968 9969 const run_cmd = exe.run(); 9970 9971 const test_step = b.step("test", "Test the program"); 9972 test_step.dependOn(&run_cmd.step); 9973 } 9974 {#code_end#} 9975 <p class="file">terminal</p> 9976 <pre><code class="shell">$ zig build test 9977 1379 9978 </code></pre> 9979 {#see_also|export#} 9980 {#header_close#} 9981 {#header_open|Mixing Object Files#} 9982 <p> 9983 You can mix Zig object files with any other object files that respect the C ABI. Example: 9984 </p> 9985 <p class="file">base64.zig</p> 9986 {#code_begin|syntax#} 9987 const base64 = @import("std").base64; 9988 9989 export fn decode_base_64( 9990 dest_ptr: [*]u8, 9991 dest_len: usize, 9992 source_ptr: [*]const u8, 9993 source_len: usize, 9994 ) usize { 9995 const src = source_ptr[0..source_len]; 9996 const dest = dest_ptr[0..dest_len]; 9997 const base64_decoder = base64.standard.Decoder; 9998 const decoded_size = base64_decoder.calcSizeForSlice(src) catch unreachable; 9999 base64_decoder.decode(dest[0..decoded_size], src) catch unreachable; 10000 return decoded_size; 10001 } 10002 {#code_end#} 10003 <p class="file">test.c</p> 10004 <pre><code class="cpp">// This header is generated by zig from base64.zig 10005 #include "base64.h" 10006 10007 #include <string.h> 10008 #include <stdio.h> 10009 10010 int main(int argc, char **argv) { 10011 const char *encoded = "YWxsIHlvdXIgYmFzZSBhcmUgYmVsb25nIHRvIHVz"; 10012 char buf[200]; 10013 10014 size_t len = decode_base_64(buf, 200, encoded, strlen(encoded)); 10015 buf[len] = 0; 10016 puts(buf); 10017 10018 return 0; 10019 }</code></pre> 10020 <p class="file">build.zig</p> 10021 {#code_begin|syntax#} 10022 const Builder = @import("std").build.Builder; 10023 10024 pub fn build(b: *Builder) void { 10025 const obj = b.addObject("base64", "base64.zig"); 10026 10027 const exe = b.addExecutable("test", null); 10028 exe.addCSourceFile("test.c", &[_][]const u8{"-std=c99"}); 10029 exe.addObject(obj); 10030 exe.linkSystemLibrary("c"); 10031 exe.install(); 10032 } 10033 {#code_end#} 10034 <p class="file">terminal</p> 10035 <pre><code class="shell">$ zig build 10036 $ ./zig-out/bin/test 10037 all your base are belong to us</code></pre> 10038 {#see_also|Targets|Zig Build System#} 10039 {#header_close#} 10040 {#header_close#} 10041 {#header_open|WebAssembly#} 10042 <p>Zig supports building for WebAssembly out of the box.</p> 10043 {#header_open|Freestanding#} 10044 <p>For host environments like the web browser and nodejs, build as a dynamic library using the freestanding 10045 OS target. Here's an example of running Zig code compiled to WebAssembly with nodejs.</p> 10046 {#code_begin|lib|math#} 10047 {#target_wasm#} 10048 {#link_mode_dynamic#} 10049 extern fn print(i32) void; 10050 10051 export fn add(a: i32, b: i32) void { 10052 print(a + b); 10053 } 10054 {#code_end#} 10055 {#header_close#} 10056 <p class="file">test.js</p> 10057 <pre><code>const fs = require('fs'); 10058 const source = fs.readFileSync("./math.wasm"); 10059 const typedArray = new Uint8Array(source); 10060 10061 WebAssembly.instantiate(typedArray, { 10062 env: { 10063 print: (result) => { console.log(`The result is ${result}`); } 10064 }}).then(result => { 10065 const add = result.instance.exports.add; 10066 add(1, 2); 10067 });</code></pre> 10068 <pre><code>$ node test.js 10069 The result is 3</code></pre> 10070 {#header_open|WASI#} 10071 <p>Zig's support for WebAssembly System Interface (WASI) is under active development. 10072 Example of using the standard library and reading command line arguments:</p> 10073 {#code_begin|exe|args#} 10074 {#target_wasi#} 10075 const std = @import("std"); 10076 10077 pub fn main() !void { 10078 var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){}; 10079 const gpa = &general_purpose_allocator.allocator; 10080 const args = try std.process.argsAlloc(gpa); 10081 defer std.process.argsFree(gpa, args); 10082 10083 for (args) |arg, i| { 10084 std.debug.print("{}: {s}\n", .{ i, arg }); 10085 } 10086 } 10087 {#code_end#} 10088 <pre><code>$ wasmtime args.wasm 123 hello 10089 0: args.wasm 10090 1: 123 10091 2: hello</code></pre> 10092 <p>A more interesting example would be extracting the list of preopens from the runtime. 10093 This is now supported in the standard library via {#syntax#}std.fs.wasi.PreopenList{#endsyntax#}:</p> 10094 {#code_begin|exe|preopens#} 10095 {#target_wasi#} 10096 const std = @import("std"); 10097 const PreopenList = std.fs.wasi.PreopenList; 10098 10099 pub fn main() !void { 10100 var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){}; 10101 const gpa = &general_purpose_allocator.allocator; 10102 10103 var preopens = PreopenList.init(gpa); 10104 defer preopens.deinit(); 10105 10106 try preopens.populate(); 10107 10108 for (preopens.asSlice()) |preopen, i| { 10109 std.debug.print("{}: {}\n", .{ i, preopen }); 10110 } 10111 } 10112 {#code_end#} 10113 <pre><code>$ wasmtime --dir=. preopens.wasm 10114 0: Preopen{ .fd = 3, .type = PreopenType{ .Dir = '.' } } 10115 </code></pre> 10116 {#header_close#} 10117 {#header_close#} 10118 {#header_open|Targets#} 10119 <p> 10120 Zig supports generating code for all targets that LLVM supports. Here is 10121 what it looks like to execute <code>zig targets</code> on a Linux x86_64 10122 computer: 10123 </p> 10124 <pre><code class="shell">$ zig targets 10125 Architectures: 10126 arm 10127 v8_4a 10128 v8_3a 10129 v8_2a 10130 v8_1a 10131 v8 10132 v8r 10133 v8m_baseline 10134 v8m_mainline 10135 v7 10136 v7em 10137 v7m 10138 v7s 10139 v7k 10140 v7ve 10141 v6 10142 v6m 10143 v6k 10144 v6t2 10145 v5 10146 v5te 10147 v4t 10148 armeb 10149 v8_4a 10150 v8_3a 10151 v8_2a 10152 v8_1a 10153 v8 10154 v8r 10155 v8m_baseline 10156 v8m_mainline 10157 v7 10158 v7em 10159 v7m 10160 v7s 10161 v7k 10162 v7ve 10163 v6 10164 v6m 10165 v6k 10166 v6t2 10167 v5 10168 v5te 10169 v4t 10170 aarch64 10171 v8_4a 10172 v8_3a 10173 v8_2a 10174 v8_1a 10175 v8 10176 v8r 10177 v8m_baseline 10178 v8m_mainline 10179 aarch64_be 10180 v8_4a 10181 v8_3a 10182 v8_2a 10183 v8_1a 10184 v8 10185 v8r 10186 v8m_baseline 10187 v8m_mainline 10188 avr 10189 bpfel 10190 bpfeb 10191 hexagon 10192 mips 10193 mipsel 10194 mips64 10195 mips64el 10196 msp430 10197 powerpc 10198 powerpc64 10199 powerpc64le 10200 r600 10201 amdgcn 10202 riscv32 10203 riscv64 10204 sparc 10205 sparcv9 10206 sparcel 10207 s390x 10208 thumb 10209 v8_4a 10210 v8_3a 10211 v8_2a 10212 v8_1a 10213 v8 10214 v8r 10215 v8m_baseline 10216 v8m_mainline 10217 v7 10218 v7em 10219 v7m 10220 v7s 10221 v7k 10222 v7ve 10223 v6 10224 v6m 10225 v6k 10226 v6t2 10227 v5 10228 v5te 10229 v4t 10230 thumbeb 10231 v8_4a 10232 v8_3a 10233 v8_2a 10234 v8_1a 10235 v8 10236 v8r 10237 v8m_baseline 10238 v8m_mainline 10239 v7 10240 v7em 10241 v7m 10242 v7s 10243 v7k 10244 v7ve 10245 v6 10246 v6m 10247 v6k 10248 v6t2 10249 v5 10250 v5te 10251 v4t 10252 i386 10253 x86_64 (native) 10254 xcore 10255 nvptx 10256 nvptx64 10257 lanai 10258 wasm32 10259 wasm64 10260 10261 Operating Systems: 10262 freestanding 10263 ananas 10264 cloudabi 10265 dragonfly 10266 freebsd 10267 fuchsia 10268 ios 10269 kfreebsd 10270 linux (native) 10271 lv2 10272 macos 10273 netbsd 10274 openbsd 10275 solaris 10276 windows 10277 haiku 10278 minix 10279 rtems 10280 nacl 10281 cnk 10282 aix 10283 cuda 10284 nvcl 10285 amdhsa 10286 ps4 10287 elfiamcu 10288 tvos 10289 wasi 10290 watchos 10291 mesa3d 10292 contiki 10293 amdpal 10294 zen 10295 uefi 10296 10297 C ABIs: 10298 none 10299 gnu (native) 10300 gnuabin32 10301 gnuabi64 10302 gnueabi 10303 gnueabihf 10304 gnux32 10305 code16 10306 eabi 10307 eabihf 10308 android 10309 musl 10310 musleabi 10311 musleabihf 10312 msvc 10313 itanium 10314 cygnus 10315 coreclr 10316 simulator 10317 10318 Available libcs: 10319 aarch64_be-linux-gnu 10320 aarch64_be-linux-musl 10321 aarch64-linux-gnu 10322 aarch64-linux-musleabi 10323 armeb-linux-gnueabi 10324 armeb-linux-gnueabihf 10325 armeb-linux-musleabi 10326 armeb-linux-musleabihf 10327 arm-linux-gnueabi 10328 arm-linux-gnueabihf 10329 arm-linux-musleabi 10330 arm-linux-musleabihf 10331 i386-linux-gnu 10332 i386-linux-musl 10333 mips64el-linux-gnuabi64 10334 mips64el-linux-gnuabin32 10335 mips64el-linux-musl 10336 mips64-linux-gnuabi64 10337 mips64-linux-gnuabin32 10338 mips64-linux-musl 10339 mipsel-linux-gnu 10340 mipsel-linux-musl 10341 mips-linux-gnu 10342 mips-linux-musl 10343 nios2-linux-gnu 10344 powerpc64le-linux-gnu 10345 powerpc64le-linux-musl 10346 powerpc64-linux-gnu 10347 powerpc64-linux-musl 10348 powerpc-linux-gnu 10349 powerpc-linux-musl 10350 riscv32-linux-musl 10351 riscv64-linux-gnu 10352 riscv64-linux-musl 10353 s390x-linux-gnu 10354 s390x-linux-musl 10355 sparc-linux-gnu 10356 sparcv9-linux-gnu 10357 wasm32-freestanding-musl 10358 wasm32-wasi-musl 10359 x86_64-linux-gnu 10360 x86_64-linux-gnux32 10361 x86_64-linux-musl</code></pre> 10362 <p> 10363 The Zig Standard Library ({#syntax#}@import("std"){#endsyntax#}) has architecture, environment, and operating system 10364 abstractions, and thus takes additional work to support more platforms. 10365 Not all standard library code requires operating system abstractions, however, 10366 so things such as generic data structures work on all above platforms. 10367 </p> 10368 <p>The current list of targets supported by the Zig Standard Library is:</p> 10369 <ul> 10370 <li>Linux x86_64</li> 10371 <li>Windows x86_64</li> 10372 <li>macOS x86_64</li> 10373 </ul> 10374 {#header_close#} 10375 {#header_open|Style Guide#} 10376 <p> 10377 These coding conventions are not enforced by the compiler, but they are shipped in 10378 this documentation along with the compiler in order to provide a point of 10379 reference, should anyone wish to point to an authority on agreed upon Zig 10380 coding style. 10381 </p> 10382 {#header_open|Whitespace#} 10383 <ul> 10384 <li> 10385 4 space indentation 10386 </li> 10387 <li> 10388 Open braces on same line, unless you need to wrap. 10389 </li> 10390 <li>If a list of things is longer than 2, put each item on its own line and 10391 exercise the ability to put an extra comma at the end. 10392 </li> 10393 <li> 10394 Line length: aim for 100; use common sense. 10395 </li> 10396 </ul> 10397 {#header_close#} 10398 {#header_open|Names#} 10399 <p> 10400 Roughly speaking: {#syntax#}camelCaseFunctionName{#endsyntax#}, {#syntax#}TitleCaseTypeName{#endsyntax#}, 10401 {#syntax#}snake_case_variable_name{#endsyntax#}. More precisely: 10402 </p> 10403 <ul> 10404 <li> 10405 If {#syntax#}x{#endsyntax#} is a {#syntax#}type{#endsyntax#} 10406 then {#syntax#}x{#endsyntax#} should be {#syntax#}TitleCase{#endsyntax#}, unless it 10407 is a {#syntax#}struct{#endsyntax#} with 0 fields and is never meant to be instantiated, 10408 in which case it is considered to be a "namespace" and uses {#syntax#}snake_case{#endsyntax#}. 10409 </li> 10410 <li> 10411 If {#syntax#}x{#endsyntax#} is callable, and {#syntax#}x{#endsyntax#}'s return type is 10412 {#syntax#}type{#endsyntax#}, then {#syntax#}x{#endsyntax#} should be {#syntax#}TitleCase{#endsyntax#}. 10413 </li> 10414 <li> 10415 If {#syntax#}x{#endsyntax#} is otherwise callable, then {#syntax#}x{#endsyntax#} should 10416 be {#syntax#}camelCase{#endsyntax#}. 10417 </li> 10418 <li> 10419 Otherwise, {#syntax#}x{#endsyntax#} should be {#syntax#}snake_case{#endsyntax#}. 10420 </li> 10421 </ul> 10422 <p> 10423 Acronyms, initialisms, proper nouns, or any other word that has capitalization 10424 rules in written English are subject to naming conventions just like any other 10425 word. Even acronyms that are only 2 letters long are subject to these 10426 conventions. 10427 </p> 10428 <p> 10429 File names fall into two categories: types and namespaces. If the file 10430 (implicitly a struct) has top level fields, it should be named like any 10431 other struct with fields using {#syntax#}TitleCase{#endsyntax#}. Otherwise, 10432 it should use {#syntax#}snake_case{#endsyntax#}. Directory names should be 10433 {#syntax#}snake_case{#endsyntax#}. 10434 </p> 10435 <p> 10436 These are general rules of thumb; if it makes sense to do something different, 10437 do what makes sense. For example, if there is an established convention such as 10438 {#syntax#}ENOENT{#endsyntax#}, follow the established convention. 10439 </p> 10440 {#header_close#} 10441 {#header_open|Examples#} 10442 {#code_begin|syntax#} 10443 const namespace_name = @import("dir_name/file_name.zig"); 10444 const TypeName = @import("dir_name/TypeName.zig"); 10445 var global_var: i32 = undefined; 10446 const const_name = 42; 10447 const primitive_type_alias = f32; 10448 const string_alias = []u8; 10449 10450 const StructName = struct { 10451 field: i32, 10452 }; 10453 const StructAlias = StructName; 10454 10455 fn functionName(param_name: TypeName) void { 10456 var functionPointer = functionName; 10457 functionPointer(); 10458 functionPointer = otherFunction; 10459 functionPointer(); 10460 } 10461 const functionAlias = functionName; 10462 10463 fn ListTemplateFunction(comptime ChildType: type, comptime fixed_size: usize) type { 10464 return List(ChildType, fixed_size); 10465 } 10466 10467 fn ShortList(comptime T: type, comptime n: usize) type { 10468 return struct { 10469 field_name: [n]T, 10470 fn methodName() void {} 10471 }; 10472 } 10473 10474 // The word XML loses its casing when used in Zig identifiers. 10475 const xml_document = 10476 \\<?xml version="1.0" encoding="UTF-8"?> 10477 \\<document> 10478 \\</document> 10479 ; 10480 const XmlParser = struct { 10481 field: i32, 10482 }; 10483 10484 // The initials BE (Big Endian) are just another word in Zig identifier names. 10485 fn readU32Be() u32 {} 10486 {#code_end#} 10487 <p> 10488 See the Zig Standard Library for more examples. 10489 </p> 10490 {#header_close#} 10491 {#header_close#} 10492 {#header_open|Source Encoding#} 10493 <p>Zig source code is encoded in UTF-8. An invalid UTF-8 byte sequence results in a compile error.</p> 10494 <p>Throughout all zig source code (including in comments), some code points are never allowed:</p> 10495 <ul> 10496 <li>Ascii control characters, except for U+000a (LF), U+000d (CR), and U+0009 (HT): U+0000 - U+0008, U+000b - U+000c, U+000e - U+0001f, U+007f.</li> 10497 <li>Non-Ascii Unicode line endings: U+0085 (NEL), U+2028 (LS), U+2029 (PS).</li> 10498 </ul> 10499 <p> 10500 LF (byte value 0x0a, code point U+000a, {#syntax#}'\n'{#endsyntax#}) is the line terminator in Zig source code. 10501 This byte value terminates every line of zig source code except the last line of the file. 10502 It is recommended that non-empty source files end with an empty line, which means the last byte would be 0x0a (LF). 10503 </p> 10504 <p> 10505 Each LF may be immediately preceded by a single CR (byte value 0x0d, code point U+000d, {#syntax#}'\r'{#endsyntax#}) 10506 to form a Windows style line ending, but this is discouraged. 10507 A CR in any other context is not allowed. 10508 </p> 10509 <p> 10510 HT hard tabs (byte value 0x09, code point U+0009, {#syntax#}'\t'{#endsyntax#}) are interchangeable with 10511 SP spaces (byte value 0x20, code point U+0020, {#syntax#}' '{#endsyntax#}) as a token separator, 10512 but use of hard tabs is discouraged. See {#link|Grammar#}. 10513 </p> 10514 <p> 10515 Note that running <code>zig fmt</code> on a source file will implement all recommendations mentioned here. 10516 Note also that the stage1 compiler does <a href="https://github.com/ziglang/zig/wiki/FAQ#why-does-zig-force-me-to-use-spaces-instead-of-tabs">not yet support CR or HT</a> control characters. 10517 </p> 10518 <p> 10519 Note that a tool reading Zig source code can make assumptions if the source code is assumed to be correct Zig code. 10520 For example, when identifying the ends of lines, a tool can use a naive search such as <code>/\n/</code>, 10521 or an <a href="https://msdn.microsoft.com/en-us/library/dd409797.aspx">advanced</a> 10522 search such as <code>/\r\n?|[\n\u0085\u2028\u2029]/</code>, and in either case line endings will be correctly identified. 10523 For another example, when identifying the whitespace before the first token on a line, 10524 a tool can either use a naive search such as <code>/[ \t]/</code>, 10525 or an <a href="https://tc39.es/ecma262/#sec-characterclassescape">advanced</a> search such as <code>/\s/</code>, 10526 and in either case whitespace will be correctly identified. 10527 </p> 10528 {#header_close#} 10529 10530 {#header_open|Keyword Reference#} 10531 <div class="table-wrapper"> 10532 <table> 10533 <tr> 10534 <th> 10535 Keyword 10536 </th> 10537 <th> 10538 Description 10539 </th> 10540 </tr> 10541 <tr> 10542 <td> 10543 <pre>{#syntax#}align{#endsyntax#}</pre> 10544 </td> 10545 <td> 10546 {#syntax#}align{#endsyntax#} can be used to specify the alignment of a pointer. 10547 It can also be used after a variable or function declaration to specify the alignment of pointers to that variable or function. 10548 <ul> 10549 <li>See also {#link|Alignment#}</li> 10550 </ul> 10551 </td> 10552 </tr> 10553 <tr> 10554 <td> 10555 <pre>{#syntax#}allowzero{#endsyntax#}</pre> 10556 </td> 10557 <td> 10558 The pointer attribute {#syntax#}allowzero{#endsyntax#} allows a pointer to have address zero. 10559 <ul> 10560 <li>See also {#link|allowzero#}</li> 10561 </ul> 10562 </td> 10563 </tr> 10564 <tr> 10565 <td> 10566 <pre>{#syntax#}and{#endsyntax#}</pre> 10567 </td> 10568 <td> 10569 The boolean operator {#syntax#}and{#endsyntax#}. 10570 <ul> 10571 <li>See also {#link|Operators#}</li> 10572 </ul> 10573 </td> 10574 </tr> 10575 <tr> 10576 <td> 10577 <pre>{#syntax#}anyframe{#endsyntax#}</pre> 10578 </td> 10579 <td> 10580 {#syntax#}anyframe{#endsyntax#} can be used as a type for variables which hold pointers to function frames. 10581 <ul> 10582 <li>See also {#link|Async Functions#}</li> 10583 </ul> 10584 </td> 10585 </tr> 10586 <tr> 10587 <td> 10588 <pre>{#syntax#}anytype{#endsyntax#}</pre> 10589 </td> 10590 <td> 10591 Function parameters and struct fields can be declared with {#syntax#}anytype{#endsyntax#} in place of the type. 10592 The type will be inferred where the function is called or the struct is instantiated. 10593 <ul> 10594 <li>See also {#link|Function Parameter Type Inference#}</li> 10595 </ul> 10596 </td> 10597 </tr> 10598 <tr> 10599 <td> 10600 <pre>{#syntax#}asm{#endsyntax#}</pre> 10601 </td> 10602 <td> 10603 {#syntax#}asm{#endsyntax#} begins an inline assembly expression. This allows for directly controlling the machine code generated on compilation. 10604 <ul> 10605 <li>See also {#link|Assembly#}</li> 10606 </ul> 10607 </td> 10608 </tr> 10609 <tr> 10610 <td> 10611 <pre>{#syntax#}async{#endsyntax#}</pre> 10612 </td> 10613 <td> 10614 {#syntax#}async{#endsyntax#} can be used before a function call to get a pointer to the function's frame when it suspends. 10615 <ul> 10616 <li>See also {#link|Async Functions#}</li> 10617 </ul> 10618 </td> 10619 </tr> 10620 <tr> 10621 <td> 10622 <pre>{#syntax#}await{#endsyntax#}</pre> 10623 </td> 10624 <td> 10625 {#syntax#}await{#endsyntax#} can be used to suspend the current function until the frame provided after the {#syntax#}await{#endsyntax#} completes. 10626 {#syntax#}await{#endsyntax#} copies the value returned from the target function's frame to the caller. 10627 <ul> 10628 <li>See also {#link|Async Functions#}</li> 10629 </ul> 10630 </td> 10631 </tr> 10632 <tr> 10633 <td> 10634 <pre>{#syntax#}break{#endsyntax#}</pre> 10635 </td> 10636 <td> 10637 {#syntax#}break{#endsyntax#} can be used with a block label to return a value from the block. 10638 It can also be used to exit a loop before iteration completes naturally. 10639 <ul> 10640 <li>See also {#link|blocks#}, {#link|while#}, {#link|for#}</li> 10641 </ul> 10642 </td> 10643 </tr> 10644 <tr> 10645 <td> 10646 <pre>{#syntax#}catch{#endsyntax#}</pre> 10647 </td> 10648 <td> 10649 {#syntax#}catch{#endsyntax#} can be used to evaluate an expression if the expression before it evaluates to an error. 10650 The expression after the {#syntax#}catch{#endsyntax#} can optionally capture the error value. 10651 <ul> 10652 <li>See also {#link|catch#}, {#link|Operators#}</li> 10653 </ul> 10654 </td> 10655 </tr> 10656 <tr> 10657 <td> 10658 <pre>{#syntax#}comptime{#endsyntax#}</pre> 10659 </td> 10660 <td> 10661 {#syntax#}comptime{#endsyntax#} before a declaration can be used to label variables or function parameters as known at compile time. 10662 It can also be used to guarantee an expression is run at compile time. 10663 <ul> 10664 <li>See also {#link|comptime#}</li> 10665 </ul> 10666 </td> 10667 </tr> 10668 <tr> 10669 <td> 10670 <pre>{#syntax#}const{#endsyntax#}</pre> 10671 </td> 10672 <td> 10673 {#syntax#}const{#endsyntax#} declares a variable that can not be modified. 10674 Used as a pointer attribute, it denotes the value referenced by the pointer cannot be modified. 10675 <ul> 10676 <li>See also {#link|Variables#}</li> 10677 </ul> 10678 </td> 10679 </tr> 10680 <tr> 10681 <td> 10682 <pre>{#syntax#}continue{#endsyntax#}</pre> 10683 </td> 10684 <td> 10685 {#syntax#}continue{#endsyntax#} can be used in a loop to jump back to the beginning of the loop. 10686 <ul> 10687 <li>See also {#link|while#}, {#link|for#}</li> 10688 </ul> 10689 </td> 10690 </tr> 10691 <tr> 10692 <td> 10693 <pre>{#syntax#}defer{#endsyntax#}</pre> 10694 </td> 10695 <td> 10696 {#syntax#}defer{#endsyntax#} will execute an expression when control flow leaves the current block. 10697 <ul> 10698 <li>See also {#link|defer#}</li> 10699 </ul> 10700 </td> 10701 </tr> 10702 <tr> 10703 <td> 10704 <pre>{#syntax#}else{#endsyntax#}</pre> 10705 </td> 10706 <td> 10707 {#syntax#}else{#endsyntax#} can be used to provide an alternate branch for {#syntax#}if{#endsyntax#}, {#syntax#}switch{#endsyntax#}, 10708 {#syntax#}while{#endsyntax#}, and {#syntax#}for{#endsyntax#} expressions. 10709 <ul> 10710 <li>If used after an if expression, the else branch will be executed if the test value returns false, null, or an error.</li> 10711 <li>If used within a switch expression, the else branch will be executed if the test value matches no other cases.</li> 10712 <li>If used after a loop expression, the else branch will be executed if the loop finishes without breaking.</li> 10713 <li>See also {#link|if#}, {#link|switch#}, {#link|while#}, {#link|for#}</li> 10714 </ul> 10715 </td> 10716 </tr> 10717 <tr> 10718 <td> 10719 <pre>{#syntax#}enum{#endsyntax#}</pre> 10720 </td> 10721 <td> 10722 {#syntax#}enum{#endsyntax#} defines an enum type. 10723 <ul> 10724 <li>See also {#link|enum#}</li> 10725 </ul> 10726 </td> 10727 </tr> 10728 <tr> 10729 <td> 10730 <pre>{#syntax#}errdefer{#endsyntax#}</pre> 10731 </td> 10732 <td> 10733 {#syntax#}errdefer{#endsyntax#} will execute an expression when control flow leaves the current block if the function returns an error. 10734 <ul> 10735 <li>See also {#link|errdefer#}</li> 10736 </ul> 10737 </td> 10738 </tr> 10739 <tr> 10740 <td> 10741 <pre>{#syntax#}error{#endsyntax#}</pre> 10742 </td> 10743 <td> 10744 {#syntax#}error{#endsyntax#} defines an error type. 10745 <ul> 10746 <li>See also {#link|Errors#}</li> 10747 </ul> 10748 </td> 10749 </tr> 10750 <tr> 10751 <td> 10752 <pre>{#syntax#}export{#endsyntax#}</pre> 10753 </td> 10754 <td> 10755 {#syntax#}export{#endsyntax#} makes a function or variable externally visible in the generated object file. 10756 Exported functions default to the C calling convention. 10757 <ul> 10758 <li>See also {#link|Functions#}</li> 10759 </ul> 10760 </td> 10761 </tr> 10762 <tr> 10763 <td> 10764 <pre>{#syntax#}extern{#endsyntax#}</pre> 10765 </td> 10766 <td> 10767 {#syntax#}extern{#endsyntax#} can be used to declare a function or variable that will be resolved at link time, when linking statically 10768 or at runtime, when linking dynamically. 10769 <ul> 10770 <li>See also {#link|Functions#}</li> 10771 </ul> 10772 </td> 10773 </tr> 10774 <tr> 10775 <td> 10776 <pre>{#syntax#}false{#endsyntax#}</pre> 10777 </td> 10778 <td> 10779 The boolean value {#syntax#}false{#endsyntax#}. 10780 <ul> 10781 <li>See also {#link|Primitive Values#}</li> 10782 </ul> 10783 </td> 10784 </tr> 10785 <tr> 10786 <td> 10787 <pre>{#syntax#}fn{#endsyntax#}</pre> 10788 </td> 10789 <td> 10790 {#syntax#}fn{#endsyntax#} declares a function. 10791 <ul> 10792 <li>See also {#link|Functions#}</li> 10793 </ul> 10794 </td> 10795 </tr> 10796 <tr> 10797 <td> 10798 <pre>{#syntax#}for{#endsyntax#}</pre> 10799 </td> 10800 <td> 10801 A {#syntax#}for{#endsyntax#} expression can be used to iterate over the elements of a slice, array, or tuple. 10802 <ul> 10803 <li>See also {#link|for#}</li> 10804 </ul> 10805 </td> 10806 </tr> 10807 <tr> 10808 <td> 10809 <pre>{#syntax#}if{#endsyntax#}</pre> 10810 </td> 10811 <td> 10812 An {#syntax#}if{#endsyntax#} expression can test boolean expressions, optional values, or error unions. 10813 For optional values or error unions, the if expression can capture the unwrapped value. 10814 <ul> 10815 <li>See also {#link|if#}</li> 10816 </ul> 10817 </td> 10818 </tr> 10819 <tr> 10820 <td> 10821 <pre>{#syntax#}inline{#endsyntax#}</pre> 10822 </td> 10823 <td> 10824 {#syntax#}inline{#endsyntax#} can be used to label a loop expression such that it will be unrolled at compile time. 10825 It can also be used to force a function to be inlined at all call sites. 10826 <ul> 10827 <li>See also {#link|inline while#}, {#link|inline for#}, {#link|Functions#}</li> 10828 </ul> 10829 </td> 10830 </tr> 10831 <tr> 10832 <td> 10833 <pre>{#syntax#}noalias{#endsyntax#}</pre> 10834 </td> 10835 <td> 10836 The {#syntax#}noalias{#endsyntax#} keyword. 10837 <ul> 10838 <li>TODO add documentation for noalias</li> 10839 </ul> 10840 </td> 10841 </tr> 10842 <tr> 10843 <td> 10844 <pre>{#syntax#}nosuspend{#endsyntax#}</pre> 10845 </td> 10846 <td> 10847 The {#syntax#}nosuspend{#endsyntax#} keyword can be used in front of a block, statement or expression, to mark a scope where no suspension points are reached. 10848 In particular, inside a {#syntax#}nosuspend{#endsyntax#} scope: 10849 <ul> 10850 <li>Using the {#syntax#}suspend{#endsyntax#} keyword results in a compile error.</li> 10851 <li>Using {#syntax#}await{#endsyntax#} on a function frame which hasn't completed yet results in safety-checked {#link|Undefined Behavior#}.</li> 10852 <li>Calling an async function may result in safety-checked {#link|Undefined Behavior#}, because it's equivalent to <code>await async some_async_fn()</code>, which contains an {#syntax#}await{#endsyntax#}.</li> 10853 </ul> 10854 Code inside a {#syntax#}nosuspend{#endsyntax#} scope does not cause the enclosing function to become an {#link|async function|Async Functions#}. 10855 <ul> 10856 <li>See also {#link|Async Functions#}</li> 10857 </ul> 10858 </td> 10859 </tr> 10860 <tr> 10861 <td> 10862 <pre>{#syntax#}null{#endsyntax#}</pre> 10863 </td> 10864 <td> 10865 The optional value {#syntax#}null{#endsyntax#}. 10866 <ul> 10867 <li>See also {#link|null#}</li> 10868 </ul> 10869 </td> 10870 </tr> 10871 <tr> 10872 <td> 10873 <pre>{#syntax#}or{#endsyntax#}</pre> 10874 </td> 10875 <td> 10876 The boolean operator {#syntax#}or{#endsyntax#}. 10877 <ul> 10878 <li>See also {#link|Operators#}</li> 10879 </ul> 10880 </td> 10881 </tr> 10882 <tr> 10883 <td> 10884 <pre>{#syntax#}orelse{#endsyntax#}</pre> 10885 </td> 10886 <td> 10887 {#syntax#}orelse{#endsyntax#} can be used to evaluate an expression if the expression before it evaluates to null. 10888 <ul> 10889 <li>See also {#link|Optionals#}, {#link|Operators#}</li> 10890 </ul> 10891 </td> 10892 </tr> 10893 <tr> 10894 <td> 10895 <pre>{#syntax#}packed{#endsyntax#}</pre> 10896 </td> 10897 <td> 10898 The {#syntax#}packed{#endsyntax#} keyword before a struct definition changes the struct's in-memory layout 10899 to the guaranteed {#syntax#}packed{#endsyntax#} layout. 10900 <ul> 10901 <li>See also {#link|packed struct#}</li> 10902 </ul> 10903 </td> 10904 </tr> 10905 <tr> 10906 <td> 10907 <pre>{#syntax#}pub{#endsyntax#}</pre> 10908 </td> 10909 <td> 10910 The {#syntax#}pub{#endsyntax#} in front of a top level declaration makes the declaration available 10911 to reference from a different file than the one it is declared in. 10912 <ul> 10913 <li>See also {#link|import#}</li> 10914 </ul> 10915 </td> 10916 </tr> 10917 <tr> 10918 <td> 10919 <pre>{#syntax#}resume{#endsyntax#}</pre> 10920 </td> 10921 <td> 10922 {#syntax#}resume{#endsyntax#} will continue execution of a function frame after the point the function was suspended. 10923 <ul> 10924 <li>See also {#link|Suspend and Resume#}</li> 10925 </ul> 10926 </td> 10927 </tr> 10928 <tr> 10929 <td> 10930 <pre>{#syntax#}return{#endsyntax#}</pre> 10931 </td> 10932 <td> 10933 {#syntax#}return{#endsyntax#} exits a function with a value. 10934 <ul> 10935 <li>See also {#link|Functions#}</li> 10936 </ul> 10937 </td> 10938 </tr> 10939 <tr> 10940 <td> 10941 <pre>{#syntax#}linksection{#endsyntax#}</pre> 10942 </td> 10943 <td> 10944 The {#syntax#}linksection{#endsyntax#} keyword. 10945 <ul> 10946 <li>TODO add documentation for linksection</li> 10947 </ul> 10948 </td> 10949 </tr> 10950 <tr> 10951 <td> 10952 <pre>{#syntax#}struct{#endsyntax#}</pre> 10953 </td> 10954 <td> 10955 {#syntax#}struct{#endsyntax#} defines a struct. 10956 <ul> 10957 <li>See also {#link|struct#}</li> 10958 </ul> 10959 </td> 10960 </tr> 10961 <tr> 10962 <td> 10963 <pre>{#syntax#}suspend{#endsyntax#}</pre> 10964 </td> 10965 <td> 10966 {#syntax#}suspend{#endsyntax#} will cause control flow to return to the call site or resumer of the function. 10967 {#syntax#}suspend{#endsyntax#} can also be used before a block within a function, 10968 to allow the function access to its frame before control flow returns to the call site. 10969 <ul> 10970 <li>See also {#link|Suspend and Resume#}</li> 10971 </ul> 10972 </td> 10973 </tr> 10974 <tr> 10975 <td> 10976 <pre>{#syntax#}switch{#endsyntax#}</pre> 10977 </td> 10978 <td> 10979 A {#syntax#}switch{#endsyntax#} expression can be used to test values of a common type. 10980 {#syntax#}switch{#endsyntax#} cases can capture field values of a {#link|Tagged union#}. 10981 <ul> 10982 <li>See also {#link|switch#}</li> 10983 </ul> 10984 </td> 10985 </tr> 10986 <tr> 10987 <td> 10988 <pre>{#syntax#}test{#endsyntax#}</pre> 10989 </td> 10990 <td> 10991 The {#syntax#}test{#endsyntax#} keyword can be used to denote a top-level block of code 10992 used to make sure behavior meets expectations. 10993 <ul> 10994 <li>See also {#link|Zig Test#}</li> 10995 </ul> 10996 </td> 10997 </tr> 10998 <tr> 10999 <td> 11000 <pre>{#syntax#}threadlocal{#endsyntax#}</pre> 11001 </td> 11002 <td> 11003 {#syntax#}threadlocal{#endsyntax#} can be used to specify a variable as thread-local. 11004 <ul> 11005 <li>See also {#link|Thread Local Variables#}</li> 11006 </ul> 11007 </td> 11008 </tr> 11009 <tr> 11010 <td> 11011 <pre>{#syntax#}true{#endsyntax#}</pre> 11012 </td> 11013 <td> 11014 The boolean value {#syntax#}true{#endsyntax#}. 11015 <ul> 11016 <li>See also {#link|Primitive Values#}</li> 11017 </ul> 11018 </td> 11019 </tr> 11020 <tr> 11021 <td> 11022 <pre>{#syntax#}try{#endsyntax#}</pre> 11023 </td> 11024 <td> 11025 {#syntax#}try{#endsyntax#} evaluates an error union expression. 11026 If it is an error, it returns from the current function with the same error. 11027 Otherwise, the expression results in the unwrapped value. 11028 <ul> 11029 <li>See also {#link|try#}</li> 11030 </ul> 11031 </td> 11032 </tr> 11033 <tr> 11034 <td> 11035 <pre>{#syntax#}undefined{#endsyntax#}</pre> 11036 </td> 11037 <td> 11038 {#syntax#}undefined{#endsyntax#} can be used to leave a value uninitialized. 11039 <ul> 11040 <li>See also {#link|undefined#}</li> 11041 </ul> 11042 </td> 11043 </tr> 11044 <tr> 11045 <td> 11046 <pre>{#syntax#}union{#endsyntax#}</pre> 11047 </td> 11048 <td> 11049 {#syntax#}union{#endsyntax#} defines a union. 11050 <ul> 11051 <li>See also {#link|union#}</li> 11052 </ul> 11053 </td> 11054 </tr> 11055 <tr> 11056 <td> 11057 <pre>{#syntax#}unreachable{#endsyntax#}</pre> 11058 </td> 11059 <td> 11060 {#syntax#}unreachable{#endsyntax#} can be used to assert that control flow will never happen upon a particular location. 11061 Depending on the build mode, {#syntax#}unreachable{#endsyntax#} may emit a panic. 11062 <ul> 11063 <li>Emits a panic in {#syntax#}Debug{#endsyntax#} and {#syntax#}ReleaseSafe{#endsyntax#} mode, or when using <code>zig test</code>.</li> 11064 <li>Does not emit a panic in {#syntax#}ReleaseFast{#endsyntax#} mode, unless <code>zig test</code> is being used.</li> 11065 <li>See also {#link|unreachable#}</li> 11066 </ul> 11067 </td> 11068 </tr> 11069 <tr> 11070 <td> 11071 <pre>{#syntax#}usingnamespace{#endsyntax#}</pre> 11072 </td> 11073 <td> 11074 {#syntax#}usingnamespace{#endsyntax#} is a top-level declaration that imports all the public declarations of the operand, 11075 which must be a struct, union, or enum, into the current scope. 11076 <ul> 11077 <li>See also {#link|usingnamespace#}</li> 11078 </ul> 11079 </td> 11080 </tr> 11081 <tr> 11082 <td> 11083 <pre>{#syntax#}var{#endsyntax#}</pre> 11084 </td> 11085 <td> 11086 {#syntax#}var{#endsyntax#} declares a variable that may be modified. 11087 <ul> 11088 <li>See also {#link|Variables#}</li> 11089 </ul> 11090 </td> 11091 </tr> 11092 <tr> 11093 <td> 11094 <pre>{#syntax#}volatile{#endsyntax#}</pre> 11095 </td> 11096 <td> 11097 {#syntax#}volatile{#endsyntax#} can be used to denote loads or stores of a pointer have side effects. 11098 It can also modify an inline assembly expression to denote it has side effects. 11099 <ul> 11100 <li>See also {#link|volatile#}, {#link|Assembly#}</li> 11101 </ul> 11102 </td> 11103 </tr> 11104 <tr> 11105 <td> 11106 <pre>{#syntax#}while{#endsyntax#}</pre> 11107 </td> 11108 <td> 11109 A {#syntax#}while{#endsyntax#} expression can be used to repeatedly test a boolean, optional, or error union expression, 11110 and cease looping when that expression evaluates to false, null, or an error, respectively. 11111 <ul> 11112 <li>See also {#link|while#}</li> 11113 </ul> 11114 </td> 11115 </tr> 11116 </table> 11117 </div> 11118 {#header_close#} 11119 11120 {#header_open|Grammar#} 11121 <pre><code>Root <- skip container_doc_comment? ContainerMembers eof 11122 11123 # *** Top level *** 11124 ContainerMembers <- ContainerDeclarations (ContainerField COMMA)* (ContainerField / ContainerDeclarations) 11125 11126 ContainerDeclarations 11127 <- TestDecl ContainerDeclarations 11128 / TopLevelComptime ContainerDeclarations 11129 / doc_comment? KEYWORD_pub? TopLevelDecl ContainerDeclarations 11130 / 11131 11132 TestDecl <- doc_comment? KEYWORD_test STRINGLITERALSINGLE? Block 11133 11134 TopLevelComptime <- doc_comment? KEYWORD_comptime BlockExpr 11135 11136 TopLevelDecl 11137 <- (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE? / (KEYWORD_inline / KEYWORD_noinline))? FnProto (SEMICOLON / Block) 11138 / (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? VarDecl 11139 / KEYWORD_usingnamespace Expr SEMICOLON 11140 11141 FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? CallConv? EXCLAMATIONMARK? TypeExpr 11142 11143 VarDecl <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON 11144 11145 ContainerField <- doc_comment? KEYWORD_comptime? IDENTIFIER (COLON (KEYWORD_anytype / TypeExpr) ByteAlign?)? (EQUAL Expr)? 11146 11147 # *** Block Level *** 11148 Statement 11149 <- KEYWORD_comptime? VarDecl 11150 / KEYWORD_comptime BlockExprStatement 11151 / KEYWORD_nosuspend BlockExprStatement 11152 / KEYWORD_suspend BlockExprStatement 11153 / KEYWORD_defer BlockExprStatement 11154 / KEYWORD_errdefer Payload? BlockExprStatement 11155 / IfStatement 11156 / LabeledStatement 11157 / SwitchExpr 11158 / AssignExpr SEMICOLON 11159 11160 IfStatement 11161 <- IfPrefix BlockExpr ( KEYWORD_else Payload? Statement )? 11162 / IfPrefix AssignExpr ( SEMICOLON / KEYWORD_else Payload? Statement ) 11163 11164 LabeledStatement <- BlockLabel? (Block / LoopStatement) 11165 11166 LoopStatement <- KEYWORD_inline? (ForStatement / WhileStatement) 11167 11168 ForStatement 11169 <- ForPrefix BlockExpr ( KEYWORD_else Statement )? 11170 / ForPrefix AssignExpr ( SEMICOLON / KEYWORD_else Statement ) 11171 11172 WhileStatement 11173 <- WhilePrefix BlockExpr ( KEYWORD_else Payload? Statement )? 11174 / WhilePrefix AssignExpr ( SEMICOLON / KEYWORD_else Payload? Statement ) 11175 11176 BlockExprStatement 11177 <- BlockExpr 11178 / AssignExpr SEMICOLON 11179 11180 BlockExpr <- BlockLabel? Block 11181 11182 # *** Expression Level *** 11183 AssignExpr <- Expr (AssignOp Expr)? 11184 11185 Expr <- BoolOrExpr 11186 11187 BoolOrExpr <- BoolAndExpr (KEYWORD_or BoolAndExpr)* 11188 11189 BoolAndExpr <- CompareExpr (KEYWORD_and CompareExpr)* 11190 11191 CompareExpr <- BitwiseExpr (CompareOp BitwiseExpr)? 11192 11193 BitwiseExpr <- BitShiftExpr (BitwiseOp BitShiftExpr)* 11194 11195 BitShiftExpr <- AdditionExpr (BitShiftOp AdditionExpr)* 11196 11197 AdditionExpr <- MultiplyExpr (AdditionOp MultiplyExpr)* 11198 11199 MultiplyExpr <- PrefixExpr (MultiplyOp PrefixExpr)* 11200 11201 PrefixExpr <- PrefixOp* PrimaryExpr 11202 11203 PrimaryExpr 11204 <- AsmExpr 11205 / IfExpr 11206 / KEYWORD_break BreakLabel? Expr? 11207 / KEYWORD_comptime Expr 11208 / KEYWORD_nosuspend Expr 11209 / KEYWORD_continue BreakLabel? 11210 / KEYWORD_resume Expr 11211 / KEYWORD_return Expr? 11212 / BlockLabel? LoopExpr 11213 / Block 11214 / CurlySuffixExpr 11215 11216 IfExpr <- IfPrefix Expr (KEYWORD_else Payload? Expr)? 11217 11218 Block <- LBRACE Statement* RBRACE 11219 11220 LoopExpr <- KEYWORD_inline? (ForExpr / WhileExpr) 11221 11222 ForExpr <- ForPrefix Expr (KEYWORD_else Expr)? 11223 11224 WhileExpr <- WhilePrefix Expr (KEYWORD_else Payload? Expr)? 11225 11226 CurlySuffixExpr <- TypeExpr InitList? 11227 11228 InitList 11229 <- LBRACE FieldInit (COMMA FieldInit)* COMMA? RBRACE 11230 / LBRACE Expr (COMMA Expr)* COMMA? RBRACE 11231 / LBRACE RBRACE 11232 11233 TypeExpr <- PrefixTypeOp* ErrorUnionExpr 11234 11235 ErrorUnionExpr <- SuffixExpr (EXCLAMATIONMARK TypeExpr)? 11236 11237 SuffixExpr 11238 <- KEYWORD_async PrimaryTypeExpr SuffixOp* FnCallArguments 11239 / PrimaryTypeExpr (SuffixOp / FnCallArguments)* 11240 11241 PrimaryTypeExpr 11242 <- BUILTINIDENTIFIER FnCallArguments 11243 / CHAR_LITERAL 11244 / ContainerDecl 11245 / DOT IDENTIFIER 11246 / DOT InitList 11247 / ErrorSetDecl 11248 / FLOAT 11249 / FnProto 11250 / GroupedExpr 11251 / LabeledTypeExpr 11252 / IDENTIFIER 11253 / IfTypeExpr 11254 / INTEGER 11255 / KEYWORD_comptime TypeExpr 11256 / KEYWORD_error DOT IDENTIFIER 11257 / KEYWORD_false 11258 / KEYWORD_null 11259 / KEYWORD_anyframe 11260 / KEYWORD_true 11261 / KEYWORD_undefined 11262 / KEYWORD_unreachable 11263 / STRINGLITERAL 11264 / SwitchExpr 11265 11266 ContainerDecl <- (KEYWORD_extern / KEYWORD_packed)? ContainerDeclAuto 11267 11268 ErrorSetDecl <- KEYWORD_error LBRACE IdentifierList RBRACE 11269 11270 GroupedExpr <- LPAREN Expr RPAREN 11271 11272 IfTypeExpr <- IfPrefix TypeExpr (KEYWORD_else Payload? TypeExpr)? 11273 11274 LabeledTypeExpr 11275 <- BlockLabel Block 11276 / BlockLabel? LoopTypeExpr 11277 11278 LoopTypeExpr <- KEYWORD_inline? (ForTypeExpr / WhileTypeExpr) 11279 11280 ForTypeExpr <- ForPrefix TypeExpr (KEYWORD_else TypeExpr)? 11281 11282 WhileTypeExpr <- WhilePrefix TypeExpr (KEYWORD_else Payload? TypeExpr)? 11283 11284 SwitchExpr <- KEYWORD_switch LPAREN Expr RPAREN LBRACE SwitchProngList RBRACE 11285 11286 # *** Assembly *** 11287 AsmExpr <- KEYWORD_asm KEYWORD_volatile? LPAREN Expr AsmOutput? RPAREN 11288 11289 AsmOutput <- COLON AsmOutputList AsmInput? 11290 11291 AsmOutputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN (MINUSRARROW TypeExpr / IDENTIFIER) RPAREN 11292 11293 AsmInput <- COLON AsmInputList AsmClobbers? 11294 11295 AsmInputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN Expr RPAREN 11296 11297 AsmClobbers <- COLON StringList 11298 11299 # *** Helper grammar *** 11300 BreakLabel <- COLON IDENTIFIER 11301 11302 BlockLabel <- IDENTIFIER COLON 11303 11304 FieldInit <- DOT IDENTIFIER EQUAL Expr 11305 11306 WhileContinueExpr <- COLON LPAREN AssignExpr RPAREN 11307 11308 LinkSection <- KEYWORD_linksection LPAREN Expr RPAREN 11309 11310 # Fn specific 11311 CallConv <- KEYWORD_callconv LPAREN Expr RPAREN 11312 11313 ParamDecl 11314 <- doc_comment? (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType 11315 / DOT3 11316 11317 ParamType 11318 <- KEYWORD_anytype 11319 / TypeExpr 11320 11321 # Control flow prefixes 11322 IfPrefix <- KEYWORD_if LPAREN Expr RPAREN PtrPayload? 11323 11324 WhilePrefix <- KEYWORD_while LPAREN Expr RPAREN PtrPayload? WhileContinueExpr? 11325 11326 ForPrefix <- KEYWORD_for LPAREN Expr RPAREN PtrIndexPayload 11327 11328 # Payloads 11329 Payload <- PIPE IDENTIFIER PIPE 11330 11331 PtrPayload <- PIPE ASTERISK? IDENTIFIER PIPE 11332 11333 PtrIndexPayload <- PIPE ASTERISK? IDENTIFIER (COMMA IDENTIFIER)? PIPE 11334 11335 11336 # Switch specific 11337 SwitchProng <- SwitchCase EQUALRARROW PtrPayload? AssignExpr 11338 11339 SwitchCase 11340 <- SwitchItem (COMMA SwitchItem)* COMMA? 11341 / KEYWORD_else 11342 11343 SwitchItem <- Expr (DOT3 Expr)? 11344 11345 # Operators 11346 AssignOp 11347 <- ASTERISKEQUAL 11348 / SLASHEQUAL 11349 / PERCENTEQUAL 11350 / PLUSEQUAL 11351 / MINUSEQUAL 11352 / LARROW2EQUAL 11353 / RARROW2EQUAL 11354 / AMPERSANDEQUAL 11355 / CARETEQUAL 11356 / PIPEEQUAL 11357 / ASTERISKPERCENTEQUAL 11358 / PLUSPERCENTEQUAL 11359 / MINUSPERCENTEQUAL 11360 / EQUAL 11361 11362 CompareOp 11363 <- EQUALEQUAL 11364 / EXCLAMATIONMARKEQUAL 11365 / LARROW 11366 / RARROW 11367 / LARROWEQUAL 11368 / RARROWEQUAL 11369 11370 BitwiseOp 11371 <- AMPERSAND 11372 / CARET 11373 / PIPE 11374 / KEYWORD_orelse 11375 / KEYWORD_catch Payload? 11376 11377 BitShiftOp 11378 <- LARROW2 11379 / RARROW2 11380 11381 AdditionOp 11382 <- PLUS 11383 / MINUS 11384 / PLUS2 11385 / PLUSPERCENT 11386 / MINUSPERCENT 11387 11388 MultiplyOp 11389 <- PIPE2 11390 / ASTERISK 11391 / SLASH 11392 / PERCENT 11393 / ASTERISK2 11394 / ASTERISKPERCENT 11395 11396 PrefixOp 11397 <- EXCLAMATIONMARK 11398 / MINUS 11399 / TILDE 11400 / MINUSPERCENT 11401 / AMPERSAND 11402 / KEYWORD_try 11403 / KEYWORD_await 11404 11405 PrefixTypeOp 11406 <- QUESTIONMARK 11407 / KEYWORD_anyframe MINUSRARROW 11408 / SliceTypeStart (ByteAlign / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)* 11409 / PtrTypeStart (KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)* 11410 / ArrayTypeStart 11411 11412 SuffixOp 11413 <- LBRACKET Expr (DOT2 (Expr? (COLON Expr)?)?)? RBRACKET 11414 / DOT IDENTIFIER 11415 / DOTASTERISK 11416 / DOTQUESTIONMARK 11417 11418 FnCallArguments <- LPAREN ExprList RPAREN 11419 11420 # Ptr specific 11421 SliceTypeStart <- LBRACKET (COLON Expr)? RBRACKET 11422 11423 PtrTypeStart 11424 <- ASTERISK 11425 / ASTERISK2 11426 / LBRACKET ASTERISK (LETTERC / COLON Expr)? RBRACKET 11427 11428 ArrayTypeStart <- LBRACKET Expr (COLON Expr)? RBRACKET 11429 11430 # ContainerDecl specific 11431 ContainerDeclAuto <- ContainerDeclType LBRACE container_doc_comment? ContainerMembers RBRACE 11432 11433 ContainerDeclType 11434 <- KEYWORD_struct 11435 / KEYWORD_opaque 11436 / KEYWORD_enum (LPAREN Expr RPAREN)? 11437 / KEYWORD_union (LPAREN (KEYWORD_enum (LPAREN Expr RPAREN)? / Expr) RPAREN)? 11438 11439 # Alignment 11440 ByteAlign <- KEYWORD_align LPAREN Expr RPAREN 11441 11442 # Lists 11443 IdentifierList <- (doc_comment? IDENTIFIER COMMA)* (doc_comment? IDENTIFIER)? 11444 11445 SwitchProngList <- (SwitchProng COMMA)* SwitchProng? 11446 11447 AsmOutputList <- (AsmOutputItem COMMA)* AsmOutputItem? 11448 11449 AsmInputList <- (AsmInputItem COMMA)* AsmInputItem? 11450 11451 StringList <- (STRINGLITERAL COMMA)* STRINGLITERAL? 11452 11453 ParamDeclList <- (ParamDecl COMMA)* ParamDecl? 11454 11455 ExprList <- (Expr COMMA)* Expr? 11456 11457 # *** Tokens *** 11458 eof <- !. 11459 bin <- [01] 11460 bin_ <- '_'? bin 11461 oct <- [0-7] 11462 oct_ <- '_'? oct 11463 hex <- [0-9a-fA-F] 11464 hex_ <- '_'? hex 11465 dec <- [0-9] 11466 dec_ <- '_'? dec 11467 11468 bin_int <- bin bin_* 11469 oct_int <- oct oct_* 11470 dec_int <- dec dec_* 11471 hex_int <- hex hex_* 11472 11473 ox80_oxBF <- [\200-\277] 11474 oxF4 <- '\364' 11475 ox80_ox8F <- [\200-\217] 11476 oxF1_oxF3 <- [\361-\363] 11477 oxF0 <- '\360' 11478 ox90_0xBF <- [\220-\277] 11479 oxEE_oxEF <- [\356-\357] 11480 oxED <- '\355' 11481 ox80_ox9F <- [\200-\237] 11482 oxE1_oxEC <- [\341-\354] 11483 oxE0 <- '\340' 11484 oxA0_oxBF <- [\240-\277] 11485 oxC2_oxDF <- [\302-\337] 11486 11487 # From https://lemire.me/blog/2018/05/09/how-quickly-can-you-check-that-a-string-is-valid-unicode-utf-8/ 11488 # First Byte Second Byte Third Byte Fourth Byte 11489 # [0x00,0x7F] 11490 # [0xC2,0xDF] [0x80,0xBF] 11491 # 0xE0 [0xA0,0xBF] [0x80,0xBF] 11492 # [0xE1,0xEC] [0x80,0xBF] [0x80,0xBF] 11493 # 0xED [0x80,0x9F] [0x80,0xBF] 11494 # [0xEE,0xEF] [0x80,0xBF] [0x80,0xBF] 11495 # 0xF0 [0x90,0xBF] [0x80,0xBF] [0x80,0xBF] 11496 # [0xF1,0xF3] [0x80,0xBF] [0x80,0xBF] [0x80,0xBF] 11497 # 0xF4 [0x80,0x8F] [0x80,0xBF] [0x80,0xBF] 11498 11499 mb_utf8_literal <- 11500 oxF4 ox80_ox8F ox80_oxBF ox80_oxBF 11501 / oxF1_oxF3 ox80_oxBF ox80_oxBF ox80_oxBF 11502 / oxF0 ox90_0xBF ox80_oxBF ox80_oxBF 11503 / oxEE_oxEF ox80_oxBF ox80_oxBF 11504 / oxED ox80_ox9F ox80_oxBF 11505 / oxE1_oxEC ox80_oxBF ox80_oxBF 11506 / oxE0 oxA0_oxBF ox80_oxBF 11507 / oxC2_oxDF ox80_oxBF 11508 11509 ascii_char_not_nl_slash_squote <- [\000-\011\013-\046-\050-\133\135-\177] 11510 11511 char_escape 11512 <- "\\x" hex hex 11513 / "\\u{" hex+ "}" 11514 / "\\" [nr\\t'"] 11515 char_char 11516 <- mb_utf8_literal 11517 / char_escape 11518 / ascii_char_not_nl_slash_squote 11519 11520 string_char 11521 <- char_escape 11522 / [^\\"\n] 11523 11524 container_doc_comment <- ('//!' [^\n]* [ \n]*)+ 11525 doc_comment <- ('///' [^\n]* [ \n]*)+ 11526 line_comment <- '//' ![!/][^\n]* / '////' [^\n]* 11527 line_string <- ("\\\\" [^\n]* [ \n]*)+ 11528 skip <- ([ \n] / line_comment)* 11529 11530 CHAR_LITERAL <- "'" char_char "'" skip 11531 FLOAT 11532 <- "0x" hex_int "." hex_int ([pP] [-+]? dec_int)? skip 11533 / dec_int "." dec_int ([eE] [-+]? dec_int)? skip 11534 / "0x" hex_int "."? [pP] [-+]? dec_int skip 11535 / dec_int "."? [eE] [-+]? dec_int skip 11536 INTEGER 11537 <- "0b" bin_int skip 11538 / "0o" oct_int skip 11539 / "0x" hex_int skip 11540 / dec_int skip 11541 STRINGLITERALSINGLE <- "\"" string_char* "\"" skip 11542 STRINGLITERAL 11543 <- STRINGLITERALSINGLE 11544 / (line_string skip)+ 11545 IDENTIFIER 11546 <- !keyword [A-Za-z_] [A-Za-z0-9_]* skip 11547 / "@\"" string_char* "\"" skip 11548 BUILTINIDENTIFIER <- "@"[A-Za-z_][A-Za-z0-9_]* skip 11549 11550 11551 AMPERSAND <- '&' ![=] skip 11552 AMPERSANDEQUAL <- '&=' skip 11553 ASTERISK <- '*' ![*%=] skip 11554 ASTERISK2 <- '**' skip 11555 ASTERISKEQUAL <- '*=' skip 11556 ASTERISKPERCENT <- '*%' ![=] skip 11557 ASTERISKPERCENTEQUAL <- '*%=' skip 11558 CARET <- '^' ![=] skip 11559 CARETEQUAL <- '^=' skip 11560 COLON <- ':' skip 11561 COMMA <- ',' skip 11562 DOT <- '.' ![*.?] skip 11563 DOT2 <- '..' ![.] skip 11564 DOT3 <- '...' skip 11565 DOTASTERISK <- '.*' skip 11566 DOTQUESTIONMARK <- '.?' skip 11567 EQUAL <- '=' ![>=] skip 11568 EQUALEQUAL <- '==' skip 11569 EQUALRARROW <- '=>' skip 11570 EXCLAMATIONMARK <- '!' ![=] skip 11571 EXCLAMATIONMARKEQUAL <- '!=' skip 11572 LARROW <- '<' ![<=] skip 11573 LARROW2 <- '<<' ![=] skip 11574 LARROW2EQUAL <- '<<=' skip 11575 LARROWEQUAL <- '<=' skip 11576 LBRACE <- '{' skip 11577 LBRACKET <- '[' skip 11578 LPAREN <- '(' skip 11579 MINUS <- '-' ![%=>] skip 11580 MINUSEQUAL <- '-=' skip 11581 MINUSPERCENT <- '-%' ![=] skip 11582 MINUSPERCENTEQUAL <- '-%=' skip 11583 MINUSRARROW <- '->' skip 11584 PERCENT <- '%' ![=] skip 11585 PERCENTEQUAL <- '%=' skip 11586 PIPE <- '|' ![|=] skip 11587 PIPE2 <- '||' skip 11588 PIPEEQUAL <- '|=' skip 11589 PLUS <- '+' ![%+=] skip 11590 PLUS2 <- '++' skip 11591 PLUSEQUAL <- '+=' skip 11592 PLUSPERCENT <- '+%' ![=] skip 11593 PLUSPERCENTEQUAL <- '+%=' skip 11594 LETTERC <- 'c' skip 11595 QUESTIONMARK <- '?' skip 11596 RARROW <- '>' ![>=] skip 11597 RARROW2 <- '>>' ![=] skip 11598 RARROW2EQUAL <- '>>=' skip 11599 RARROWEQUAL <- '>=' skip 11600 RBRACE <- '}' skip 11601 RBRACKET <- ']' skip 11602 RPAREN <- ')' skip 11603 SEMICOLON <- ';' skip 11604 SLASH <- '/' ![=] skip 11605 SLASHEQUAL <- '/=' skip 11606 TILDE <- '~' skip 11607 11608 end_of_word <- ![a-zA-Z0-9_] skip 11609 KEYWORD_align <- 'align' end_of_word 11610 KEYWORD_allowzero <- 'allowzero' end_of_word 11611 KEYWORD_and <- 'and' end_of_word 11612 KEYWORD_anyframe <- 'anyframe' end_of_word 11613 KEYWORD_anytype <- 'anytype' end_of_word 11614 KEYWORD_asm <- 'asm' end_of_word 11615 KEYWORD_async <- 'async' end_of_word 11616 KEYWORD_await <- 'await' end_of_word 11617 KEYWORD_break <- 'break' end_of_word 11618 KEYWORD_callconv <- 'callconv' end_of_word 11619 KEYWORD_catch <- 'catch' end_of_word 11620 KEYWORD_comptime <- 'comptime' end_of_word 11621 KEYWORD_const <- 'const' end_of_word 11622 KEYWORD_continue <- 'continue' end_of_word 11623 KEYWORD_defer <- 'defer' end_of_word 11624 KEYWORD_else <- 'else' end_of_word 11625 KEYWORD_enum <- 'enum' end_of_word 11626 KEYWORD_errdefer <- 'errdefer' end_of_word 11627 KEYWORD_error <- 'error' end_of_word 11628 KEYWORD_export <- 'export' end_of_word 11629 KEYWORD_extern <- 'extern' end_of_word 11630 KEYWORD_false <- 'false' end_of_word 11631 KEYWORD_fn <- 'fn' end_of_word 11632 KEYWORD_for <- 'for' end_of_word 11633 KEYWORD_if <- 'if' end_of_word 11634 KEYWORD_inline <- 'inline' end_of_word 11635 KEYWORD_noalias <- 'noalias' end_of_word 11636 KEYWORD_nosuspend <- 'nosuspend' end_of_word 11637 KEYWORD_noinline <- 'noinline' end_of_word 11638 KEYWORD_null <- 'null' end_of_word 11639 KEYWORD_opaque <- 'opaque' end_of_word 11640 KEYWORD_or <- 'or' end_of_word 11641 KEYWORD_orelse <- 'orelse' end_of_word 11642 KEYWORD_packed <- 'packed' end_of_word 11643 KEYWORD_pub <- 'pub' end_of_word 11644 KEYWORD_resume <- 'resume' end_of_word 11645 KEYWORD_return <- 'return' end_of_word 11646 KEYWORD_linksection <- 'linksection' end_of_word 11647 KEYWORD_struct <- 'struct' end_of_word 11648 KEYWORD_suspend <- 'suspend' end_of_word 11649 KEYWORD_switch <- 'switch' end_of_word 11650 KEYWORD_test <- 'test' end_of_word 11651 KEYWORD_threadlocal <- 'threadlocal' end_of_word 11652 KEYWORD_true <- 'true' end_of_word 11653 KEYWORD_try <- 'try' end_of_word 11654 KEYWORD_undefined <- 'undefined' end_of_word 11655 KEYWORD_union <- 'union' end_of_word 11656 KEYWORD_unreachable <- 'unreachable' end_of_word 11657 KEYWORD_usingnamespace <- 'usingnamespace' end_of_word 11658 KEYWORD_var <- 'var' end_of_word 11659 KEYWORD_volatile <- 'volatile' end_of_word 11660 KEYWORD_while <- 'while' end_of_word 11661 11662 keyword <- KEYWORD_align / KEYWORD_allowzero / KEYWORD_and / KEYWORD_anyframe 11663 / KEYWORD_anytype / KEYWORD_asm / KEYWORD_async / KEYWORD_await 11664 / KEYWORD_break / KEYWORD_callconv / KEYWORD_catch / KEYWORD_comptime 11665 / KEYWORD_const / KEYWORD_continue / KEYWORD_defer / KEYWORD_else 11666 / KEYWORD_enum / KEYWORD_errdefer / KEYWORD_error / KEYWORD_export 11667 / KEYWORD_extern / KEYWORD_false / KEYWORD_fn / KEYWORD_for / KEYWORD_if 11668 / KEYWORD_inline / KEYWORD_noalias / KEYWORD_nosuspend / KEYWORD_noinline 11669 / KEYWORD_null / KEYWORD_opaque / KEYWORD_or / KEYWORD_orelse / KEYWORD_packed 11670 / KEYWORD_pub / KEYWORD_resume / KEYWORD_return / KEYWORD_linksection 11671 / KEYWORD_struct / KEYWORD_suspend / KEYWORD_switch 11672 / KEYWORD_test / KEYWORD_threadlocal / KEYWORD_true / KEYWORD_try 11673 / KEYWORD_undefined / KEYWORD_union / KEYWORD_unreachable 11674 / KEYWORD_usingnamespace / KEYWORD_var / KEYWORD_volatile / KEYWORD_while 11675 </code></pre> 11676 {#header_close#} 11677 {#header_open|Zen#} 11678 <ul> 11679 <li>Communicate intent precisely.</li> 11680 <li>Edge cases matter.</li> 11681 <li>Favor reading code over writing code.</li> 11682 <li>Only one obvious way to do things.</li> 11683 <li>Runtime crashes are better than bugs.</li> 11684 <li>Compile errors are better than runtime crashes.</li> 11685 <li>Incremental improvements.</li> 11686 <li>Avoid local maximums.</li> 11687 <li>Reduce the amount one must remember.</li> 11688 <li>Focus on code rather than style.</li> 11689 <li>Resource allocation may fail; resource deallocation must succeed.</li> 11690 <li>Memory is a resource.</li> 11691 <li>Together we serve the users.</li> 11692 </ul> 11693 {#header_close#} 11694 </div></div> 11695 </div> 11696 </body> 11697 </html>