blob 3bd1124e (219925B) - Raw
1 <!doctype html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" /> 6 <title>Documentation - The Zig Programming Language</title> 7 <style type="text/css"> 8 .hljs{display:block;overflow-x:auto;padding:0.5em;color:#333;background:#f8f8f8}.hljs-comment,.hljs-quote{color:#998;font-style:italic}.hljs-keyword,.hljs-selector-tag,.hljs-subst{color:#333;font-weight:bold}.hljs-number,.hljs-literal,.hljs-variable,.hljs-template-variable,.hljs-tag .hljs-attr{color:#008080}.hljs-string,.hljs-doctag{color:#d14}.hljs-title,.hljs-section,.hljs-selector-id{color:#900;font-weight:bold}.hljs-subst{font-weight:normal}.hljs-type,.hljs-class .hljs-title{color:#458;font-weight:bold}.hljs-tag,.hljs-name,.hljs-attribute{color:#000080;font-weight:normal}.hljs-regexp,.hljs-link{color:#009926}.hljs-symbol,.hljs-bullet{color:#990073}.hljs-built_in,.hljs-builtin-name{color:#0086b3}.hljs-meta{color:#999;font-weight:bold}.hljs-deletion{background:#fdd}.hljs-addition{background:#dfd}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold} 9 </style> 10 <style type="text/css"> 11 table, th, td { 12 border-collapse: collapse; 13 border: 1px solid grey; 14 } 15 th, td { 16 padding: 0.1em; 17 } 18 .t0_1, .t37, .t37_1 { 19 font-weight: bold; 20 } 21 .t2_0 { 22 color: grey; 23 } 24 .t31_1 { 25 color: red; 26 } 27 .t32_1 { 28 color: green; 29 } 30 .t36_1 { 31 color: #0086b3; 32 } 33 .file { 34 text-decoration: underline; 35 } 36 code { 37 font-size: 12pt; 38 } 39 pre > code { 40 display: block; 41 overflow: auto; 42 } 43 .table-wrapper { 44 width: 100%; 45 overflow-y: auto; 46 } 47 /* Desktop */ 48 @media screen and (min-width: 56.25em) { 49 #nav { 50 width: 20em; 51 height: 100%; 52 position: fixed; 53 overflow-y: scroll; 54 left: 0; 55 top: 0; 56 padding-left: 1em; 57 } 58 #contents { 59 max-width: 60em; 60 padding-left: 22em; 61 padding: 1em; 62 padding-left: 24em; 63 } 64 } 65 /* Mobile */ 66 @media screen and (max-width: 56.25em) { 67 body, code { 68 font-size: small; 69 } 70 #nav { 71 border-bottom: 1px solid grey; 72 } 73 } 74 </style> 75 </head> 76 <body> 77 <div id="nav"> 78 <h3>Index</h3> 79 {#nav#} 80 </div> 81 <div id="contents"> 82 {#header_open|Introduction#} 83 <p> 84 Zig is an open-source programming language designed for <strong>robustness</strong>, 85 <strong>optimality</strong>, and <strong>clarity</strong>. 86 </p> 87 <ul> 88 <li><strong>Robust</strong> - behavior is correct even for edge cases such as out of memory.</li> 89 <li><strong>Optimal</strong> - write programs the best way they can behave and perform.</li> 90 <li><strong>Clear</strong> - precisely communicate your intent to the compiler and other programmers. The language imposes a low overhead to reading code.</li> 91 </ul> 92 <p> 93 Often the most efficient way to learn something new is to see examples, so 94 this documentation shows how to use each of Zig's features. It is 95 all on one page so you can search with your browser's search tool. 96 </p> 97 <p> 98 If you search for something specific in this documentation and do not find it, 99 please <a href="https://github.com/ziglang/www.ziglang.org/issues/new?title=I%20searched%20for%20___%20in%20the%20docs%20and%20didn%27t%20find%20it">file an issue</a> or <a href="https://webchat.freenode.net/?channels=%23zig">say something on IRC</a>. 100 </p> 101 <p> 102 The code samples in this document are compiled and tested as part of the main test suite of Zig. 103 This HTML document depends on no external files, so you can use it offline. 104 </p> 105 {#header_close#} 106 {#header_open|Hello World#} 107 108 {#code_begin|exe|hello#} 109 const std = @import("std"); 110 111 pub fn main() !void { 112 // If this program is run without stdout attached, exit with an error. 113 var stdout_file = try std.io.getStdOut(); 114 // If this program encounters pipe failure when printing to stdout, exit 115 // with an error. 116 try stdout_file.write("Hello, world!\n"); 117 } 118 {#code_end#} 119 <p> 120 Usually you don't want to write to stdout. You want to write to stderr. And you 121 don't care if it fails. It's more like a <em>warning message</em> that you want 122 to emit. For that you can use a simpler API: 123 </p> 124 {#code_begin|exe|hello#} 125 const warn = @import("std").debug.warn; 126 127 pub fn main() void { 128 warn("Hello, world!\n"); 129 } 130 {#code_end#} 131 <p> 132 Note that we also left off the <code class="zig">!</code> from the return type. 133 In Zig, if your main function cannot fail, you must use the <code class="zig">void</code> return type. 134 </p> 135 {#see_also|Values|@import|Errors|Root Source File#} 136 {#header_close#} 137 {#header_open|Values#} 138 {#code_begin|exe|values#} 139 const std = @import("std"); 140 const warn = std.debug.warn; 141 const os = std.os; 142 const assert = std.debug.assert; 143 144 pub fn main() void { 145 // integers 146 const one_plus_one: i32 = 1 + 1; 147 warn("1 + 1 = {}\n", one_plus_one); 148 149 // floats 150 const seven_div_three: f32 = 7.0 / 3.0; 151 warn("7.0 / 3.0 = {}\n", seven_div_three); 152 153 // boolean 154 warn("{}\n{}\n{}\n", 155 true and false, 156 true or false, 157 !true); 158 159 // nullable 160 var nullable_value: ?[]const u8 = null; 161 assert(nullable_value == null); 162 163 warn("\nnullable 1\ntype: {}\nvalue: {}\n", 164 @typeName(@typeOf(nullable_value)), nullable_value); 165 166 nullable_value = "hi"; 167 assert(nullable_value != null); 168 169 warn("\nnullable 2\ntype: {}\nvalue: {}\n", 170 @typeName(@typeOf(nullable_value)), nullable_value); 171 172 // error union 173 var number_or_error: error!i32 = error.ArgNotFound; 174 175 warn("\nerror union 1\ntype: {}\nvalue: {}\n", 176 @typeName(@typeOf(number_or_error)), number_or_error); 177 178 number_or_error = 1234; 179 180 warn("\nerror union 2\ntype: {}\nvalue: {}\n", 181 @typeName(@typeOf(number_or_error)), number_or_error); 182 } 183 {#code_end#} 184 {#header_open|Primitive Types#} 185 <div class="table-wrapper"> 186 <table> 187 <tr> 188 <th> 189 Name 190 </th> 191 <th> 192 C Equivalent 193 </th> 194 <th> 195 Description 196 </th> 197 </tr> 198 <tr> 199 <td><code>i2</code></td> 200 <td><code>(none)</code></td> 201 <td>signed 2-bit integer</td> 202 </tr> 203 <tr> 204 <td><code>u2</code></td> 205 <td><code>(none)</code></td> 206 <td>unsigned 2-bit integer</td> 207 </tr> 208 <tr> 209 <td><code>i3</code></td> 210 <td><code>(none)</code></td> 211 <td>signed 3-bit integer</td> 212 </tr> 213 <tr> 214 <td><code>u3</code></td> 215 <td><code>(none)</code></td> 216 <td>unsigned 3-bit integer</td> 217 </tr> 218 <tr> 219 <td><code>i4</code></td> 220 <td><code>(none)</code></td> 221 <td>signed 4-bit integer</td> 222 </tr> 223 <tr> 224 <td><code>u4</code></td> 225 <td><code>(none)</code></td> 226 <td>unsigned 4-bit integer</td> 227 </tr> 228 <tr> 229 <td><code>i5</code></td> 230 <td><code>(none)</code></td> 231 <td>signed 5-bit integer</td> 232 </tr> 233 <tr> 234 <td><code>u5</code></td> 235 <td><code>(none)</code></td> 236 <td>unsigned 5-bit integer</td> 237 </tr> 238 <tr> 239 <td><code>i6</code></td> 240 <td><code>(none)</code></td> 241 <td>signed 6-bit integer</td> 242 </tr> 243 <tr> 244 <td><code>u6</code></td> 245 <td><code>(none)</code></td> 246 <td>unsigned 6-bit integer</td> 247 </tr> 248 <tr> 249 <td><code>i7</code></td> 250 <td><code>(none)</code></td> 251 <td>signed 7-bit integer</td> 252 </tr> 253 <tr> 254 <td><code>u7</code></td> 255 <td><code>(none)</code></td> 256 <td>unsigned 7-bit integer</td> 257 </tr> 258 <tr> 259 <td><code>i8</code></td> 260 <td><code>int8_t</code></td> 261 <td>signed 8-bit integer</td> 262 </tr> 263 <tr> 264 <td><code>u8</code></td> 265 <td><code>uint8_t</code></td> 266 <td>unsigned 8-bit integer</td> 267 </tr> 268 <tr> 269 <td><code>i16</code></td> 270 <td><code>int16_t</code></td> 271 <td>signed 16-bit integer</td> 272 </tr> 273 <tr> 274 <td><code>u16</code></td> 275 <td><code>uint16_t</code></td> 276 <td>unsigned 16-bit integer</td> 277 </tr> 278 <tr> 279 <td><code>i32</code></td> 280 <td><code>int32_t</code></td> 281 <td>signed 32-bit integer</td> 282 </tr> 283 <tr> 284 <td><code>u32</code></td> 285 <td><code>uint32_t</code></td> 286 <td>unsigned 32-bit integer</td> 287 </tr> 288 <tr> 289 <td><code>i64</code></td> 290 <td><code>int64_t</code></td> 291 <td>signed 64-bit integer</td> 292 </tr> 293 <tr> 294 <td><code>u64</code></td> 295 <td><code>uint64_t</code></td> 296 <td>unsigned 64-bit integer</td> 297 </tr> 298 <tr> 299 <td><code>i128</code></td> 300 <td><code>__int128</code></td> 301 <td>signed 128-bit integer</td> 302 </tr> 303 <tr> 304 <td><code>u128</code></td> 305 <td><code>unsigned __int128</code></td> 306 <td>unsigned 128-bit integer</td> 307 </tr> 308 <tr> 309 <td><code>isize</code></td> 310 <td><code>intptr_t</code></td> 311 <td>signed pointer sized integer</td> 312 </tr> 313 <tr> 314 <td><code>usize</code></td> 315 <td><code>uintptr_t</code></td> 316 <td>unsigned pointer sized integer</td> 317 </tr> 318 319 <tr> 320 <td><code>c_short</code></td> 321 <td><code>short</code></td> 322 <td>for ABI compatibility with C</td> 323 </tr> 324 <tr> 325 <td><code>c_ushort</code></td> 326 <td><code>unsigned short</code></td> 327 <td>for ABI compatibility with C</td> 328 </tr> 329 <tr> 330 <td><code>c_int</code></td> 331 <td><code>int</code></td> 332 <td>for ABI compatibility with C</td> 333 </tr> 334 <tr> 335 <td><code>c_uint</code></td> 336 <td><code>unsigned int</code></td> 337 <td>for ABI compatibility with C</td> 338 </tr> 339 <tr> 340 <td><code>c_long</code></td> 341 <td><code>long</code></td> 342 <td>for ABI compatibility with C</td> 343 </tr> 344 <tr> 345 <td><code>c_ulong</code></td> 346 <td><code>unsigned long</code></td> 347 <td>for ABI compatibility with C</td> 348 </tr> 349 <tr> 350 <td><code>c_longlong</code></td> 351 <td><code>long long</code></td> 352 <td>for ABI compatibility with C</td> 353 </tr> 354 <tr> 355 <td><code>c_ulonglong</code></td> 356 <td><code>unsigned long long</code></td> 357 <td>for ABI compatibility with C</td> 358 </tr> 359 <tr> 360 <td><code>c_longdouble</code></td> 361 <td><code>long double</code></td> 362 <td>for ABI compatibility with C</td> 363 </tr> 364 <tr> 365 <td><code>c_void</code></td> 366 <td><code>void</code></td> 367 <td>for ABI compatibility with C</td> 368 </tr> 369 370 <tr> 371 <td><code>f32</code></td> 372 <td><code>float</code></td> 373 <td>32-bit floating point (23-bit mantissa)</td> 374 </tr> 375 <tr> 376 <td><code>f64</code></td> 377 <td><code>double</code></td> 378 <td>64-bit floating point (52-bit mantissa)</td> 379 </tr> 380 <tr> 381 <td><code>f128</code></td> 382 <td>(none)</td> 383 <td>128-bit floating point (112-bit mantissa)</td> 384 </tr> 385 <tr> 386 <td><code>bool</code></td> 387 <td><code>bool</code></td> 388 <td><code>true</code> or <code>false</code></td> 389 </tr> 390 <tr> 391 <td><code>void</code></td> 392 <td>(none)</td> 393 <td>0 bit type</td> 394 </tr> 395 <tr> 396 <td><code>noreturn</code></td> 397 <td>(none)</td> 398 <td>the type of <code>break</code>, <code>continue</code>, <code>return</code>, <code>unreachable</code>, and <code>while (true) {}</code></td> 399 </tr> 400 <tr> 401 <td><code>type</code></td> 402 <td>(none)</td> 403 <td>the type of types</td> 404 </tr> 405 <tr> 406 <td><code>error</code></td> 407 <td>(none)</td> 408 <td>an error code</td> 409 </tr> 410 </table> 411 </div> 412 {#see_also|Integers|Floats|void|Errors#} 413 {#header_close#} 414 {#header_open|Primitive Values#} 415 <div class="table-wrapper"> 416 <table> 417 <tr> 418 <th> 419 Name 420 </th> 421 <th> 422 Description 423 </th> 424 </tr> 425 <tr> 426 <td><code>true</code> and <code>false</code></td> 427 <td><code>bool</code> values</td> 428 </tr> 429 <tr> 430 <td><code>null</code></td> 431 <td>used to set a nullable type to <code>null</code></td> 432 </tr> 433 <tr> 434 <td><code>undefined</code></td> 435 <td>used to leave a value unspecified</td> 436 </tr> 437 <tr> 438 <td><code>this</code></td> 439 <td>refers to the thing in immediate scope</td> 440 </tr> 441 </table> 442 </div> 443 {#see_also|Nullables|this#} 444 {#header_close#} 445 {#header_open|String Literals#} 446 {#code_begin|test#} 447 const assert = @import("std").debug.assert; 448 const mem = @import("std").mem; 449 450 test "string literals" { 451 // In Zig a string literal is an array of bytes. 452 const normal_bytes = "hello"; 453 assert(@typeOf(normal_bytes) == [5]u8); 454 assert(normal_bytes.len == 5); 455 assert(normal_bytes[1] == 'e'); 456 assert('e' == '\x65'); 457 assert(mem.eql(u8, "hello", "h\x65llo")); 458 459 // A C string literal is a null terminated pointer. 460 const null_terminated_bytes = c"hello"; 461 assert(@typeOf(null_terminated_bytes) == *const u8); 462 assert(null_terminated_bytes[5] == 0); 463 } 464 {#code_end#} 465 {#see_also|Arrays|Zig Test#} 466 {#header_open|Escape Sequences#} 467 <div class="table-wrapper"> 468 <table> 469 <tr> 470 <th> 471 Escape Sequence 472 </th> 473 <th> 474 Name 475 </th> 476 </tr> 477 <tr> 478 <td><code>\n</code></td> 479 <td>Newline</td> 480 </tr> 481 <tr> 482 <td><code>\r</code></td> 483 <td>Carriage Return</td> 484 </tr> 485 <tr> 486 <td><code>\t</code></td> 487 <td>Tab</td> 488 </tr> 489 <tr> 490 <td><code>\\</code></td> 491 <td>Backslash</td> 492 </tr> 493 <tr> 494 <td><code>\'</code></td> 495 <td>Single Quote</td> 496 </tr> 497 <tr> 498 <td><code>\"</code></td> 499 <td>Double Quote</td> 500 </tr> 501 <tr> 502 <td><code>\xNN</code></td> 503 <td>hexadecimal 8-bit character code (2 digits)</td> 504 </tr> 505 <tr> 506 <td><code>\uNNNN</code></td> 507 <td>hexadecimal 16-bit Unicode character code UTF-8 encoded (4 digits)</td> 508 </tr> 509 <tr> 510 <td><code>\UNNNNNN</code></td> 511 <td>hexadecimal 24-bit Unicode character code UTF-8 encoded (6 digits)</td> 512 </tr> 513 </table> 514 </div> 515 <p>Note that the maximum valid Unicode point is <code>0x10ffff</code>.</p> 516 {#header_close#} 517 {#header_open|Multiline String Literals#} 518 <p> 519 Multiline string literals have no escapes and can span across multiple lines. 520 To start a multiline string literal, use the <code>\\</code> token. Just like a comment, 521 the string literal goes until the end of the line. The end of the line is 522 not included in the string literal. 523 However, if the next line begins with <code>\\</code> then a newline is appended and 524 the string literal continues. 525 </p> 526 {#code_begin|syntax#} 527 const hello_world_in_c = 528 \\#include <stdio.h> 529 \\ 530 \\int main(int argc, char **argv) { 531 \\ printf("hello world\n"); 532 \\ return 0; 533 \\} 534 ; 535 {#code_end#} 536 <p> 537 For a multiline C string literal, prepend <code>c</code> to each <code>\\</code>: 538 </p> 539 {#code_begin|syntax#} 540 const c_string_literal = 541 c\\#include <stdio.h> 542 c\\ 543 c\\int main(int argc, char **argv) { 544 c\\ printf("hello world\n"); 545 c\\ return 0; 546 c\\} 547 ; 548 {#code_end#} 549 <p> 550 In this example the variable <code>c_string_literal</code> has type <code>*const char</code> and 551 has a terminating null byte. 552 </p> 553 {#see_also|@embedFile#} 554 {#header_close#} 555 {#header_close#} 556 {#header_open|Assignment#} 557 <p>Use <code>const</code> to assign a value to an identifier:</p> 558 {#code_begin|test_err|cannot assign to constant#} 559 const x = 1234; 560 561 fn foo() void { 562 // It works at global scope as well as inside functions. 563 const y = 5678; 564 565 // Once assigned, an identifier cannot be changed. 566 y += 1; 567 } 568 569 test "assignment" { 570 foo(); 571 } 572 {#code_end#} 573 <p>If you need a variable that you can modify, use <code>var</code>:</p> 574 {#code_begin|test#} 575 const assert = @import("std").debug.assert; 576 577 test "var" { 578 var y: i32 = 5678; 579 580 y += 1; 581 582 assert(y == 5679); 583 } 584 {#code_end#} 585 <p>Variables must be initialized:</p> 586 {#code_begin|test_err#} 587 test "initialization" { 588 var x: i32; 589 590 x = 1; 591 } 592 {#code_end#} 593 <p>Use <code>undefined</code> to leave variables uninitialized:</p> 594 {#code_begin|test#} 595 const assert = @import("std").debug.assert; 596 597 test "init with undefined" { 598 var x: i32 = undefined; 599 x = 1; 600 assert(x == 1); 601 } 602 {#code_end#} 603 {#header_close#} 604 {#header_close#} 605 {#header_open|Integers#} 606 {#header_open|Integer Literals#} 607 {#code_begin|syntax#} 608 const decimal_int = 98222; 609 const hex_int = 0xff; 610 const another_hex_int = 0xFF; 611 const octal_int = 0o755; 612 const binary_int = 0b11110000; 613 {#code_end#} 614 {#header_close#} 615 {#header_open|Runtime Integer Values#} 616 <p> 617 Integer literals have no size limitation, and if any undefined behavior occurs, 618 the compiler catches it. 619 </p> 620 <p> 621 However, once an integer value is no longer known at compile-time, it must have a 622 known size, and is vulnerable to undefined behavior. 623 </p> 624 {#code_begin|syntax#} 625 fn divide(a: i32, b: i32) i32 { 626 return a / b; 627 } 628 {#code_end#} 629 <p> 630 In this function, values <code>a</code> and <code>b</code> are known only at runtime, 631 and thus this division operation is vulnerable to both integer overflow and 632 division by zero. 633 </p> 634 <p> 635 Operators such as <code>+</code> and <code>-</code> cause undefined behavior on 636 integer overflow. Also available are operations such as <code>+%</code> and 637 <code>-%</code> which are defined to have wrapping arithmetic on all targets. 638 </p> 639 {#see_also|Integer Overflow|Division by Zero|Wrapping Operations#} 640 {#header_close#} 641 {#header_close#} 642 {#header_open|Floats#} 643 {#header_open|Float Literals#} 644 {#code_begin|syntax#} 645 const floating_point = 123.0E+77; 646 const another_float = 123.0; 647 const yet_another = 123.0e+77; 648 649 const hex_floating_point = 0x103.70p-5; 650 const another_hex_float = 0x103.70; 651 const yet_another_hex_float = 0x103.70P-5; 652 {#code_end#} 653 {#header_close#} 654 {#header_open|Floating Point Operations#} 655 <p>By default floating point operations use <code>Optimized</code> mode, 656 but you can switch to <code>Strict</code> mode on a per-block basis:</p> 657 {#code_begin|obj|foo#} 658 {#code_release_fast#} 659 const builtin = @import("builtin"); 660 const big = f64(1 << 40); 661 662 export fn foo_strict(x: f64) f64 { 663 @setFloatMode(this, builtin.FloatMode.Strict); 664 return x + big - big; 665 } 666 667 export fn foo_optimized(x: f64) f64 { 668 return x + big - big; 669 } 670 {#code_end#} 671 <p>For this test we have to separate code into two object files - 672 otherwise the optimizer figures out all the values at compile-time, 673 which operates in strict mode.</p> 674 {#code_begin|exe|float_mode#} 675 {#code_link_object|foo#} 676 const warn = @import("std").debug.warn; 677 678 extern fn foo_strict(x: f64) f64; 679 extern fn foo_optimized(x: f64) f64; 680 681 pub fn main() void { 682 const x = 0.001; 683 warn("optimized = {}\n", foo_optimized(x)); 684 warn("strict = {}\n", foo_strict(x)); 685 } 686 {#code_end#} 687 {#see_also|@setFloatMode|Division by Zero#} 688 {#header_close#} 689 {#header_close#} 690 {#header_open|Operators#} 691 {#header_open|Table of Operators#} 692 <div class="table-wrapper"> 693 <table> 694 <tr> 695 <th> 696 Syntax 697 </th> 698 <th> 699 Relevant Types 700 </th> 701 <th> 702 Description 703 </th> 704 <th> 705 Example 706 </th> 707 </tr> 708 <tr> 709 <td><pre><code class="zig">a + b 710 a += b</code></pre></td> 711 <td> 712 <ul> 713 <li>{#link|Integers#}</li> 714 <li>{#link|Floats#}</li> 715 </ul> 716 </td> 717 <td>Addition. 718 <ul> 719 <li>Can cause {#link|overflow|Default Operations#} for integers.</li> 720 </ul> 721 </td> 722 <td> 723 <pre><code class="zig">2 + 5 == 7</code></pre> 724 </td> 725 </tr> 726 <tr> 727 <td><pre><code class="zig">a +% b 728 a +%= b</code></pre></td> 729 <td> 730 <ul> 731 <li>{#link|Integers#}</li> 732 </ul> 733 </td> 734 <td>Wrapping Addition. 735 <ul> 736 <li>Guaranteed to have twos-complement wrapping behavior.</li> 737 </ul> 738 </td> 739 <td> 740 <pre><code class="zig">u32(@maxValue(u32)) +% 1 == 0</code></pre> 741 </td> 742 </tr> 743 <tr> 744 <td><pre><code class="zig">a - b 745 a -= b</code></pre></td> 746 <td> 747 <ul> 748 <li>{#link|Integers#}</li> 749 <li>{#link|Floats#}</li> 750 </ul> 751 </td> 752 <td>Subtraction. 753 <ul> 754 <li>Can cause {#link|overflow|Default Operations#} for integers.</li> 755 </ul> 756 </td> 757 <td> 758 <pre><code class="zig">2 - 5 == -3</code></pre> 759 </td> 760 </tr> 761 <tr> 762 <td><pre><code class="zig">a -% b 763 a -%= b</code></pre></td> 764 <td> 765 <ul> 766 <li>{#link|Integers#}</li> 767 </ul> 768 </td> 769 <td>Wrapping Subtraction. 770 <ul> 771 <li>Guaranteed to have twos-complement wrapping behavior.</li> 772 </ul> 773 </td> 774 <td> 775 <pre><code class="zig">u32(0) -% 1 == @maxValue(u32)</code></pre> 776 </td> 777 </tr> 778 <tr> 779 <td><pre><code class="zig">-a<code></pre></td> 780 <td> 781 <ul> 782 <li>{#link|Integers#}</li> 783 <li>{#link|Floats#}</li> 784 </ul> 785 </td> 786 <td> 787 Negation. 788 <ul> 789 <li>Can cause {#link|overflow|Default Operations#} for integers.</li> 790 </ul> 791 </td> 792 <td> 793 <pre><code class="zig">-1 == 0 - 1</code></pre> 794 </td> 795 </tr> 796 <tr> 797 <td><pre><code class="zig">-%a<code></pre></td> 798 <td> 799 <ul> 800 <li>{#link|Integers#}</li> 801 </ul> 802 </td> 803 <td> 804 Wrapping Negation. 805 <ul> 806 <li>Guaranteed to have twos-complement wrapping behavior.</li> 807 </ul> 808 </td> 809 <td> 810 <pre><code class="zig">-%i32(@minValue(i32)) == @minValue(i32)</code></pre> 811 </td> 812 </tr> 813 <tr> 814 <td><pre><code class="zig">a * b 815 a *= b</code></pre></td> 816 <td> 817 <ul> 818 <li>{#link|Integers#}</li> 819 <li>{#link|Floats#}</li> 820 </ul> 821 </td> 822 <td>Multiplication. 823 <ul> 824 <li>Can cause {#link|overflow|Default Operations#} for integers.</li> 825 </ul> 826 </td> 827 <td> 828 <pre><code class="zig">2 * 5 == 10</code></pre> 829 </td> 830 </tr> 831 <tr> 832 <td><pre><code class="zig">a *% b 833 a *%= b</code></pre></td> 834 <td> 835 <ul> 836 <li>{#link|Integers#}</li> 837 </ul> 838 </td> 839 <td>Wrapping Multiplication. 840 <ul> 841 <li>Guaranteed to have twos-complement wrapping behavior.</li> 842 </ul> 843 </td> 844 <td> 845 <pre><code class="zig">u8(200) *% 2 == 144</code></pre> 846 </td> 847 </tr> 848 <tr> 849 <td><pre><code class="zig">a / b 850 a /= b</code></pre></td> 851 <td> 852 <ul> 853 <li>{#link|Integers#}</li> 854 <li>{#link|Floats#}</li> 855 </ul> 856 </td> 857 <td>Divison. 858 <ul> 859 <li>Can cause {#link|overflow|Default Operations#} for integers.</li> 860 <li>Can cause {#link|Division by Zero#} for integers.</li> 861 <li>Can cause {#link|Division by Zero#} for floats in {#link|FloatMode.Optimized Mode|Floating Point Operations#}.</li> 862 <li>For non-compile-time-known signed integers, must use 863 {#link|@divTrunc#}, 864 {#link|@divFloor#}, or 865 {#link|@divExact#} instead of <code>/</code>. 866 </li> 867 </ul> 868 </td> 869 <td> 870 <pre><code class="zig">10 / 5 == 2</code></pre> 871 </td> 872 </tr> 873 <tr> 874 <td><pre><code class="zig">a % b 875 a %= b</code></pre></td> 876 <td> 877 <ul> 878 <li>{#link|Integers#}</li> 879 <li>{#link|Floats#}</li> 880 </ul> 881 </td> 882 <td>Remainder Division. 883 <ul> 884 <li>Can cause {#link|Division by Zero#} for integers.</li> 885 <li>Can cause {#link|Division by Zero#} for floats in {#link|FloatMode.Optimized Mode|Floating Point Operations#}.</li> 886 <li>For non-compile-time-known signed integers, must use 887 {#link|@rem#} or 888 {#link|@mod#} instead of <code>%</code>. 889 </li> 890 </ul> 891 </td> 892 <td> 893 <pre><code class="zig">10 % 3 == 1</code></pre> 894 </td> 895 </tr> 896 <tr> 897 <td><pre><code class="zig">a << b 898 a <<= b</code></pre></td> 899 <td> 900 <ul> 901 <li>{#link|Integers#}</li> 902 </ul> 903 </td> 904 <td>Bit Shift Left. 905 <ul> 906 <li>See also {#link|@shlExact#}.</li> 907 <li>See also {#link|@shlWithOverflow#}.</li> 908 </ul> 909 </td> 910 <td> 911 <pre><code class="zig">1 << 8 == 256</code></pre> 912 </td> 913 </tr> 914 <tr> 915 <td><pre><code class="zig">a >> b 916 a >>= b</code></pre></td> 917 <td> 918 <ul> 919 <li>{#link|Integers#}</li> 920 </ul> 921 </td> 922 <td>Bit Shift Right. 923 <ul> 924 <li>See also {#link|@shrExact#}.</li> 925 </ul> 926 </td> 927 <td> 928 <pre><code class="zig">10 >> 1 == 5</code></pre> 929 </td> 930 </tr> 931 <tr> 932 <td><pre><code class="zig">a & b 933 a &= b</code></pre></td> 934 <td> 935 <ul> 936 <li>{#link|Integers#}</li> 937 </ul> 938 </td> 939 <td>Bitwise AND. 940 </td> 941 <td> 942 <pre><code class="zig">0b011 & 0b101 == 0b001</code></pre> 943 </td> 944 </tr> 945 <tr> 946 <td><pre><code class="zig">a | b 947 a |= b</code></pre></td> 948 <td> 949 <ul> 950 <li>{#link|Integers#}</li> 951 </ul> 952 </td> 953 <td>Bitwise OR. 954 </td> 955 <td> 956 <pre><code class="zig">0b010 | 0b100 == 0b110</code></pre> 957 </td> 958 </tr> 959 <tr> 960 <td><pre><code class="zig">a ^ b 961 a ^= b</code></pre></td> 962 <td> 963 <ul> 964 <li>{#link|Integers#}</li> 965 </ul> 966 </td> 967 <td>Bitwise XOR. 968 </td> 969 <td> 970 <pre><code class="zig">0b011 ^ 0b101 == 0b110</code></pre> 971 </td> 972 </tr> 973 <tr> 974 <td><pre><code class="zig">~a<code></pre></td> 975 <td> 976 <ul> 977 <li>{#link|Integers#}</li> 978 </ul> 979 </td> 980 <td> 981 Bitwise NOT. 982 </td> 983 <td> 984 <pre><code class="zig">~u8(0b0101111) == 0b1010000</code></pre> 985 </td> 986 </tr> 987 <tr> 988 <td><pre><code class="zig">a ?? b</code></pre></td> 989 <td> 990 <ul> 991 <li>{#link|Nullables#}</li> 992 </ul> 993 </td> 994 <td>If <code>a</code> is <code>null</code>, 995 returns <code>b</code> ("default value"), 996 otherwise returns the unwrapped value of <code>a</code>. 997 Note that <code>b</code> may be a value of type {#link|noreturn#}. 998 </td> 999 <td> 1000 <pre><code class="zig">const value: ?u32 = null; 1001 const unwrapped = value ?? 1234; 1002 unwrapped == 1234</code></pre> 1003 </td> 1004 </tr> 1005 <tr> 1006 <td><pre><code class="zig">??a</code></pre></td> 1007 <td> 1008 <ul> 1009 <li>{#link|Nullables#}</li> 1010 </ul> 1011 </td> 1012 <td> 1013 Equivalent to: 1014 <pre><code class="zig">a ?? unreachable</code></pre> 1015 </td> 1016 <td> 1017 <pre><code class="zig">const value: ?u32 = 5678; 1018 ??value == 5678</code></pre> 1019 </td> 1020 </tr> 1021 <tr> 1022 <td><pre><code class="zig">a catch b 1023 a catch |err| b</code></pre></td> 1024 <td> 1025 <ul> 1026 <li>{#link|Error Unions|Errors#}</li> 1027 </ul> 1028 </td> 1029 <td>If <code>a</code> is an <code>error</code>, 1030 returns <code>b</code> ("default value"), 1031 otherwise returns the unwrapped value of <code>a</code>. 1032 Note that <code>b</code> may be a value of type {#link|noreturn#}. 1033 <code>err</code> is the <code>error</code> and is in scope of the expression <code>b</code>. 1034 </td> 1035 <td> 1036 <pre><code class="zig">const value: error!u32 = error.Broken; 1037 const unwrapped = value catch 1234; 1038 unwrapped == 1234</code></pre> 1039 </td> 1040 </tr> 1041 <tr> 1042 <td><pre><code class="zig">a and b<code></pre></td> 1043 <td> 1044 <ul> 1045 <li>{#link|bool|Primitive Types#}</li> 1046 </ul> 1047 </td> 1048 <td> 1049 If <code>a</code> is <code>false</code>, returns <code>false</code> 1050 without evaluating <code>b</code>. Otherwise, retuns <code>b</code>. 1051 </td> 1052 <td> 1053 <pre><code class="zig">false and true == false</code></pre> 1054 </td> 1055 </tr> 1056 <tr> 1057 <td><pre><code class="zig">a or b<code></pre></td> 1058 <td> 1059 <ul> 1060 <li>{#link|bool|Primitive Types#}</li> 1061 </ul> 1062 </td> 1063 <td> 1064 If <code>a</code> is <code>true</code>, returns <code>true</code> 1065 without evaluating <code>b</code>. Otherwise, retuns <code>b</code>. 1066 </td> 1067 <td> 1068 <pre><code class="zig">false or true == true</code></pre> 1069 </td> 1070 </tr> 1071 <tr> 1072 <td><pre><code class="zig">!a<code></pre></td> 1073 <td> 1074 <ul> 1075 <li>{#link|bool|Primitive Types#}</li> 1076 </ul> 1077 </td> 1078 <td> 1079 Boolean NOT. 1080 </td> 1081 <td> 1082 <pre><code class="zig">!false == true</code></pre> 1083 </td> 1084 </tr> 1085 <tr> 1086 <td><pre><code class="zig">a == b<code></pre></td> 1087 <td> 1088 <ul> 1089 <li>{#link|Integers#}</li> 1090 <li>{#link|Floats#}</li> 1091 <li>{#link|bool|Primitive Types#}</li> 1092 <li>{#link|type|Primitive Types#}</li> 1093 </ul> 1094 </td> 1095 <td> 1096 Returns <code>true</code> if a and b are equal, otherwise returns <code>false</code>. 1097 </td> 1098 <td> 1099 <pre><code class="zig">(1 == 1) == true</code></pre> 1100 </td> 1101 </tr> 1102 <tr> 1103 <td><pre><code class="zig">a == null<code></pre></td> 1104 <td> 1105 <ul> 1106 <li>{#link|Nullables#}</li> 1107 </ul> 1108 </td> 1109 <td> 1110 Returns <code>true</code> if a is <code>null</code>, otherwise returns <code>false</code>. 1111 </td> 1112 <td> 1113 <pre><code class="zig">const value: ?u32 = null; 1114 value == null</code></pre> 1115 </td> 1116 </tr> 1117 <tr> 1118 <td><pre><code class="zig">a != b<code></pre></td> 1119 <td> 1120 <ul> 1121 <li>{#link|Integers#}</li> 1122 <li>{#link|Floats#}</li> 1123 <li>{#link|bool|Primitive Types#}</li> 1124 <li>{#link|type|Primitive Types#}</li> 1125 </ul> 1126 </td> 1127 <td> 1128 Returns <code>false</code> if a and b are equal, otherwise returns <code>true</code>. 1129 </td> 1130 <td> 1131 <pre><code class="zig">(1 != 1) == false</code></pre> 1132 </td> 1133 </tr> 1134 <tr> 1135 <td><pre><code class="zig">a > b<code></pre></td> 1136 <td> 1137 <ul> 1138 <li>{#link|Integers#}</li> 1139 <li>{#link|Floats#}</li> 1140 </ul> 1141 </td> 1142 <td> 1143 Returns <code>true</code> if a is greater than b, otherwise returns <code>false</code>. 1144 </td> 1145 <td> 1146 <pre><code class="zig">(2 > 1) == true</code></pre> 1147 </td> 1148 </tr> 1149 <tr> 1150 <td><pre><code class="zig">a >= b<code></pre></td> 1151 <td> 1152 <ul> 1153 <li>{#link|Integers#}</li> 1154 <li>{#link|Floats#}</li> 1155 </ul> 1156 </td> 1157 <td> 1158 Returns <code>true</code> if a is greater than or equal to b, otherwise returns <code>false</code>. 1159 </td> 1160 <td> 1161 <pre><code class="zig">(2 >= 1) == true</code></pre> 1162 </td> 1163 </tr> 1164 <tr> 1165 <td><pre><code class="zig">a < b<code></pre></td> 1166 <td> 1167 <ul> 1168 <li>{#link|Integers#}</li> 1169 <li>{#link|Floats#}</li> 1170 </ul> 1171 </td> 1172 <td> 1173 Returns <code>true</code> if a is less than b, otherwise returns <code>false</code>. 1174 </td> 1175 <td> 1176 <pre><code class="zig">(1 < 2) == true</code></pre> 1177 </td> 1178 </tr> 1179 <tr> 1180 <td><pre><code class="zig">a <= b<code></pre></td> 1181 <td> 1182 <ul> 1183 <li>{#link|Integers#}</li> 1184 <li>{#link|Floats#}</li> 1185 </ul> 1186 </td> 1187 <td> 1188 Returns <code>true</code> if a is less than or equal to b, otherwise returns <code>false</code>. 1189 </td> 1190 <td> 1191 <pre><code class="zig">(1 <= 2) == true</code></pre> 1192 </td> 1193 </tr> 1194 <tr> 1195 <td><pre><code class="zig">a ++ b<code></pre></td> 1196 <td> 1197 <ul> 1198 <li>{#link|Arrays#}</li> 1199 </ul> 1200 </td> 1201 <td> 1202 Array concatenation. 1203 <ul> 1204 <li>Only available when <code>a</code> and <code>b</code> are {#link|compile-time known|comptime#}. 1205 </ul> 1206 </td> 1207 <td> 1208 <pre><code class="zig">const mem = @import("std").mem; 1209 const array1 = []u32{1,2}; 1210 const array2 = []u32{3,4}; 1211 const together = array1 ++ array2; 1212 mem.eql(u32, together, []u32{1,2,3,4})</code></pre> 1213 </td> 1214 </tr> 1215 <tr> 1216 <td><pre><code class="zig">a ** b<code></pre></td> 1217 <td> 1218 <ul> 1219 <li>{#link|Arrays#}</li> 1220 </ul> 1221 </td> 1222 <td> 1223 Array multiplication. 1224 <ul> 1225 <li>Only available when <code>a</code> and <code>b</code> are {#link|compile-time known|comptime#}. 1226 </ul> 1227 </td> 1228 <td> 1229 <pre><code class="zig">const mem = @import("std").mem; 1230 const pattern = "ab" ** 3; 1231 mem.eql(u8, pattern, "ababab")</code></pre> 1232 </td> 1233 </tr> 1234 <tr> 1235 <td><pre><code class="zig">a.*<code></pre></td> 1236 <td> 1237 <ul> 1238 <li>{#link|Pointers#}</li> 1239 </ul> 1240 </td> 1241 <td> 1242 Pointer dereference. 1243 </td> 1244 <td> 1245 <pre><code class="zig">const x: u32 = 1234; 1246 const ptr = &x; 1247 x.* == 1234</code></pre> 1248 </td> 1249 </tr> 1250 <tr> 1251 <td><pre><code class="zig">&a<code></pre></td> 1252 <td> 1253 All types 1254 </td> 1255 <td> 1256 Address of. 1257 </td> 1258 <td> 1259 <pre><code class="zig">const x: u32 = 1234; 1260 const ptr = &x; 1261 x.* == 1234</code></pre> 1262 </td> 1263 </tr> 1264 </table> 1265 </div> 1266 {#header_close#} 1267 {#header_open|Precedence#} 1268 <pre><code>x() x[] x.y 1269 a!b 1270 !x -x -%x ~x &x ?x ??x 1271 x{} x.* 1272 ! * / % ** *% 1273 + - ++ +% -% 1274 << >> 1275 & 1276 ^ 1277 | 1278 == != < > <= >= 1279 and 1280 or 1281 ?? catch 1282 = *= /= %= += -= <<= >>= &= ^= |=</code></pre> 1283 {#header_close#} 1284 {#header_close#} 1285 {#header_open|Arrays#} 1286 {#code_begin|test|arrays#} 1287 const assert = @import("std").debug.assert; 1288 const mem = @import("std").mem; 1289 1290 // array literal 1291 const message = []u8{'h', 'e', 'l', 'l', 'o'}; 1292 1293 // get the size of an array 1294 comptime { 1295 assert(message.len == 5); 1296 } 1297 1298 // a string literal is an array literal 1299 const same_message = "hello"; 1300 1301 comptime { 1302 assert(mem.eql(u8, message, same_message)); 1303 assert(@typeOf(message) == @typeOf(same_message)); 1304 } 1305 1306 test "iterate over an array" { 1307 var sum: usize = 0; 1308 for (message) |byte| { 1309 sum += byte; 1310 } 1311 assert(sum == usize('h') + usize('e') + usize('l') * 2 + usize('o')); 1312 } 1313 1314 // modifiable array 1315 var some_integers: [100]i32 = undefined; 1316 1317 test "modify an array" { 1318 for (some_integers) |*item, i| { 1319 item.* = i32(i); 1320 } 1321 assert(some_integers[10] == 10); 1322 assert(some_integers[99] == 99); 1323 } 1324 1325 // array concatenation works if the values are known 1326 // at compile time 1327 const part_one = []i32{1, 2, 3, 4}; 1328 const part_two = []i32{5, 6, 7, 8}; 1329 const all_of_it = part_one ++ part_two; 1330 comptime { 1331 assert(mem.eql(i32, all_of_it, []i32{1,2,3,4,5,6,7,8})); 1332 } 1333 1334 // remember that string literals are arrays 1335 const hello = "hello"; 1336 const world = "world"; 1337 const hello_world = hello ++ " " ++ world; 1338 comptime { 1339 assert(mem.eql(u8, hello_world, "hello world")); 1340 } 1341 1342 // ** does repeating patterns 1343 const pattern = "ab" ** 3; 1344 comptime { 1345 assert(mem.eql(u8, pattern, "ababab")); 1346 } 1347 1348 // initialize an array to zero 1349 const all_zero = []u16{0} ** 10; 1350 1351 comptime { 1352 assert(all_zero.len == 10); 1353 assert(all_zero[5] == 0); 1354 } 1355 1356 // use compile-time code to initialize an array 1357 var fancy_array = init: { 1358 var initial_value: [10]Point = undefined; 1359 for (initial_value) |*pt, i| { 1360 pt.* = Point { 1361 .x = i32(i), 1362 .y = i32(i) * 2, 1363 }; 1364 } 1365 break :init initial_value; 1366 }; 1367 const Point = struct { 1368 x: i32, 1369 y: i32, 1370 }; 1371 1372 test "compile-time array initalization" { 1373 assert(fancy_array[4].x == 4); 1374 assert(fancy_array[4].y == 8); 1375 } 1376 1377 // call a function to initialize an array 1378 var more_points = []Point{makePoint(3)} ** 10; 1379 fn makePoint(x: i32) Point { 1380 return Point { 1381 .x = x, 1382 .y = x * 2, 1383 }; 1384 } 1385 test "array initialization with function calls" { 1386 assert(more_points[4].x == 3); 1387 assert(more_points[4].y == 6); 1388 assert(more_points.len == 10); 1389 } 1390 {#code_end#} 1391 {#see_also|for|Slices#} 1392 {#header_close#} 1393 {#header_open|Pointers#} 1394 {#code_begin|test#} 1395 const assert = @import("std").debug.assert; 1396 1397 test "address of syntax" { 1398 // Get the address of a variable: 1399 const x: i32 = 1234; 1400 const x_ptr = &x; 1401 1402 // Deference a pointer: 1403 assert(x_ptr.* == 1234); 1404 1405 // When you get the address of a const variable, you get a const pointer. 1406 assert(@typeOf(x_ptr) == *const i32); 1407 1408 // If you want to mutate the value, you'd need an address of a mutable variable: 1409 var y: i32 = 5678; 1410 const y_ptr = &y; 1411 assert(@typeOf(y_ptr) == *i32); 1412 y_ptr.* += 1; 1413 assert(y_ptr.* == 5679); 1414 } 1415 1416 test "pointer array access" { 1417 // Pointers do not support pointer arithmetic. If you 1418 // need such a thing, use array index syntax: 1419 1420 var array = []u8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 1421 const ptr = &array[1]; 1422 1423 assert(array[2] == 3); 1424 ptr[1] += 1; 1425 assert(array[2] == 4); 1426 } 1427 1428 test "pointer slicing" { 1429 // In Zig, we prefer using slices over null-terminated pointers. 1430 // You can turn a pointer into a slice using slice syntax: 1431 var array = []u8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 1432 const ptr = &array[1]; 1433 const slice = ptr[1..3]; 1434 1435 assert(slice.ptr == &ptr[1]); 1436 assert(slice.len == 2); 1437 1438 // Slices have bounds checking and are therefore protected 1439 // against this kind of undefined behavior. This is one reason 1440 // we prefer slices to pointers. 1441 assert(array[3] == 4); 1442 slice[1] += 1; 1443 assert(array[3] == 5); 1444 } 1445 1446 comptime { 1447 // Pointers work at compile-time too, as long as you don't use 1448 // @ptrCast. 1449 var x: i32 = 1; 1450 const ptr = &x; 1451 ptr.* += 1; 1452 x += 1; 1453 assert(ptr.* == 3); 1454 } 1455 1456 test "@ptrToInt and @intToPtr" { 1457 // To convert an integer address into a pointer, use @intToPtr: 1458 const ptr = @intToPtr(*i32, 0xdeadbeef); 1459 1460 // To convert a pointer to an integer, use @ptrToInt: 1461 const addr = @ptrToInt(ptr); 1462 1463 assert(@typeOf(addr) == usize); 1464 assert(addr == 0xdeadbeef); 1465 } 1466 1467 comptime { 1468 // Zig is able to do this at compile-time, as long as 1469 // ptr is never dereferenced. 1470 const ptr = @intToPtr(*i32, 0xdeadbeef); 1471 const addr = @ptrToInt(ptr); 1472 assert(@typeOf(addr) == usize); 1473 assert(addr == 0xdeadbeef); 1474 } 1475 1476 test "volatile" { 1477 // In Zig, loads and stores are assumed to not have side effects. 1478 // If a given load or store should have side effects, such as 1479 // Memory Mapped Input/Output (MMIO), use `volatile`: 1480 const mmio_ptr = @intToPtr(*volatile u8, 0x12345678); 1481 1482 // Now loads and stores with mmio_ptr are guaranteed to all happen 1483 // and in the same order as in source code. 1484 assert(@typeOf(mmio_ptr) == *volatile u8); 1485 } 1486 1487 test "nullable pointers" { 1488 // Pointers cannot be null. If you want a null pointer, use the nullable 1489 // prefix `?` to make the pointer type nullable. 1490 var ptr: ?*i32 = null; 1491 1492 var x: i32 = 1; 1493 ptr = &x; 1494 1495 assert((??ptr).* == 1); 1496 1497 // Nullable pointers are the same size as normal pointers, because pointer 1498 // value 0 is used as the null value. 1499 assert(@sizeOf(?*i32) == @sizeOf(*i32)); 1500 } 1501 1502 test "pointer casting" { 1503 // To convert one pointer type to another, use @ptrCast. This is an unsafe 1504 // operation that Zig cannot protect you against. Use @ptrCast only when other 1505 // conversions are not possible. 1506 const bytes align(@alignOf(u32)) = []u8{0x12, 0x12, 0x12, 0x12}; 1507 const u32_ptr = @ptrCast(*const u32, &bytes[0]); 1508 assert(u32_ptr.* == 0x12121212); 1509 1510 // Even this example is contrived - there are better ways to do the above than 1511 // pointer casting. For example, using a slice narrowing cast: 1512 const u32_value = ([]const u32)(bytes[0..])[0]; 1513 assert(u32_value == 0x12121212); 1514 1515 // And even another way, the most straightforward way to do it: 1516 assert(@bitCast(u32, bytes) == 0x12121212); 1517 } 1518 1519 test "pointer child type" { 1520 // pointer types have a `child` field which tells you the type they point to. 1521 assert((*u32).Child == u32); 1522 } 1523 {#code_end#} 1524 {#header_open|Alignment#} 1525 <p> 1526 Each type has an <strong>alignment</strong> - a number of bytes such that, 1527 when a value of the type is loaded from or stored to memory, 1528 the memory address must be evenly divisible by this number. You can use 1529 {#link|@alignOf#} to find out this value for any type. 1530 </p> 1531 <p> 1532 Alignment depends on the CPU architecture, but is always a power of two, and 1533 less than <code>1 << 29</code>. 1534 </p> 1535 <p> 1536 In Zig, a pointer type has an alignment value. If the value is equal to the 1537 alignment of the underlying type, it can be omitted from the type: 1538 </p> 1539 {#code_begin|test#} 1540 const assert = @import("std").debug.assert; 1541 const builtin = @import("builtin"); 1542 1543 test "variable alignment" { 1544 var x: i32 = 1234; 1545 const align_of_i32 = @alignOf(@typeOf(x)); 1546 assert(@typeOf(&x) == *i32); 1547 assert(*i32 == *align(align_of_i32) i32); 1548 if (builtin.arch == builtin.Arch.x86_64) { 1549 assert((*i32).alignment == 4); 1550 } 1551 } 1552 {#code_end#} 1553 <p>In the same way that a <code>*i32</code> can be implicitly cast to a 1554 <code>*const i32</code>, a pointer with a larger alignment can be implicitly 1555 cast to a pointer with a smaller alignment, but not vice versa. 1556 </p> 1557 <p> 1558 You can specify alignment on variables and functions. If you do this, then 1559 pointers to them get the specified alignment: 1560 </p> 1561 {#code_begin|test#} 1562 const assert = @import("std").debug.assert; 1563 1564 var foo: u8 align(4) = 100; 1565 1566 test "global variable alignment" { 1567 assert(@typeOf(&foo).alignment == 4); 1568 assert(@typeOf(&foo) == *align(4) u8); 1569 const slice = (&foo)[0..1]; 1570 assert(@typeOf(slice) == []align(4) u8); 1571 } 1572 1573 fn derp() align(@sizeOf(usize) * 2) i32 { return 1234; } 1574 fn noop1() align(1) void {} 1575 fn noop4() align(4) void {} 1576 1577 test "function alignment" { 1578 assert(derp() == 1234); 1579 assert(@typeOf(noop1) == fn() align(1) void); 1580 assert(@typeOf(noop4) == fn() align(4) void); 1581 noop1(); 1582 noop4(); 1583 } 1584 {#code_end#} 1585 <p> 1586 If you have a pointer or a slice that has a small alignment, but you know that it actually 1587 has a bigger alignment, use {#link|@alignCast#} to change the 1588 pointer into a more aligned pointer. This is a no-op at runtime, but inserts a 1589 {#link|safety check|Incorrect Pointer Alignment#}: 1590 </p> 1591 {#code_begin|test_safety|incorrect alignment#} 1592 const assert = @import("std").debug.assert; 1593 1594 test "pointer alignment safety" { 1595 var array align(4) = []u32{0x11111111, 0x11111111}; 1596 const bytes = ([]u8)(array[0..]); 1597 assert(foo(bytes) == 0x11111111); 1598 } 1599 fn foo(bytes: []u8) u32 { 1600 const slice4 = bytes[1..5]; 1601 const int_slice = ([]u32)(@alignCast(4, slice4)); 1602 return int_slice[0]; 1603 } 1604 {#code_end#} 1605 {#header_close#} 1606 {#header_open|Type Based Alias Analysis#} 1607 <p>Zig uses Type Based Alias Analysis (also known as Strict Aliasing) to 1608 perform some optimizations. This means that pointers of different types must 1609 not alias the same memory, with the exception of <code>u8</code>. Pointers to 1610 <code>u8</code> can alias any memory. 1611 </p> 1612 <p>As an example, this code produces undefined behavior:</p> 1613 <pre><code class="zig">@ptrCast(*u32, f32(12.34)).*</code></pre> 1614 <p>Instead, use {#link|@bitCast#}: 1615 <pre><code class="zig">@bitCast(u32, f32(12.34))</code></pre> 1616 <p>As an added benefit, the <code>@bitcast</code> version works at compile-time.</p> 1617 {#see_also|Slices|Memory#} 1618 {#header_close#} 1619 {#header_close#} 1620 {#header_open|Slices#} 1621 {#code_begin|test_safety|index out of bounds#} 1622 const assert = @import("std").debug.assert; 1623 1624 test "basic slices" { 1625 var array = []i32{1, 2, 3, 4}; 1626 // A slice is a pointer and a length. The difference between an array and 1627 // a slice is that the array's length is part of the type and known at 1628 // compile-time, whereas the slice's length is known at runtime. 1629 // Both can be accessed with the `len` field. 1630 const slice = array[0..array.len]; 1631 assert(slice.ptr == &array[0]); 1632 assert(slice.len == array.len); 1633 1634 // Slices have array bounds checking. If you try to access something out 1635 // of bounds, you'll get a safety check failure: 1636 slice[10] += 1; 1637 } 1638 {#code_end#} 1639 <p>This is one reason we prefer slices to pointers.</p> 1640 {#code_begin|test|slices#} 1641 const assert = @import("std").debug.assert; 1642 const mem = @import("std").mem; 1643 const fmt = @import("std").fmt; 1644 1645 test "using slices for strings" { 1646 // Zig has no concept of strings. String literals are arrays of u8, and 1647 // in general the string type is []u8 (slice of u8). 1648 // Here we implicitly cast [5]u8 to []const u8 1649 const hello: []const u8 = "hello"; 1650 const world: []const u8 = "世界"; 1651 1652 var all_together: [100]u8 = undefined; 1653 // You can use slice syntax on an array to convert an array into a slice. 1654 const all_together_slice = all_together[0..]; 1655 // String concatenation example. 1656 const hello_world = try fmt.bufPrint(all_together_slice, "{} {}", hello, world); 1657 1658 // Generally, you can use UTF-8 and not worry about whether something is a 1659 // string. If you don't need to deal with individual characters, no need 1660 // to decode. 1661 assert(mem.eql(u8, hello_world, "hello 世界")); 1662 } 1663 1664 test "slice pointer" { 1665 var array: [10]u8 = undefined; 1666 const ptr = &array[0]; 1667 1668 // You can use slicing syntax to convert a pointer into a slice: 1669 const slice = ptr[0..5]; 1670 slice[2] = 3; 1671 assert(slice[2] == 3); 1672 // The slice is mutable because we sliced a mutable pointer. 1673 assert(@typeOf(slice) == []u8); 1674 1675 // You can also slice a slice: 1676 const slice2 = slice[2..3]; 1677 assert(slice2.len == 1); 1678 assert(slice2[0] == 3); 1679 } 1680 1681 test "slice widening" { 1682 // Zig supports slice widening and slice narrowing. Cast a slice of u8 1683 // to a slice of anything else, and Zig will perform the length conversion. 1684 const array align(@alignOf(u32)) = []u8{0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13}; 1685 const slice = ([]const u32)(array[0..]); 1686 assert(slice.len == 2); 1687 assert(slice[0] == 0x12121212); 1688 assert(slice[1] == 0x13131313); 1689 } 1690 {#code_end#} 1691 {#see_also|Pointers|for|Arrays#} 1692 {#header_close#} 1693 {#header_open|struct#} 1694 {#code_begin|test|structs#} 1695 // Declare a struct. 1696 // Zig gives no guarantees about the order of fields and whether or 1697 // not there will be padding. 1698 const Point = struct { 1699 x: f32, 1700 y: f32, 1701 }; 1702 1703 // Maybe we want to pass it to OpenGL so we want to be particular about 1704 // how the bytes are arranged. 1705 const Point2 = packed struct { 1706 x: f32, 1707 y: f32, 1708 }; 1709 1710 1711 // Declare an instance of a struct. 1712 const p = Point { 1713 .x = 0.12, 1714 .y = 0.34, 1715 }; 1716 1717 // Maybe we're not ready to fill out some of the fields. 1718 var p2 = Point { 1719 .x = 0.12, 1720 .y = undefined, 1721 }; 1722 1723 // Structs can have methods 1724 // Struct methods are not special, they are only namespaced 1725 // functions that you can call with dot syntax. 1726 const Vec3 = struct { 1727 x: f32, 1728 y: f32, 1729 z: f32, 1730 1731 pub fn init(x: f32, y: f32, z: f32) Vec3 { 1732 return Vec3 { 1733 .x = x, 1734 .y = y, 1735 .z = z, 1736 }; 1737 } 1738 1739 pub fn dot(self: *const Vec3, other: *const Vec3) f32 { 1740 return self.x * other.x + self.y * other.y + self.z * other.z; 1741 } 1742 }; 1743 1744 const assert = @import("std").debug.assert; 1745 test "dot product" { 1746 const v1 = Vec3.init(1.0, 0.0, 0.0); 1747 const v2 = Vec3.init(0.0, 1.0, 0.0); 1748 assert(v1.dot(v2) == 0.0); 1749 1750 // Other than being available to call with dot syntax, struct methods are 1751 // not special. You can reference them as any other declaration inside 1752 // the struct: 1753 assert(Vec3.dot(v1, v2) == 0.0); 1754 } 1755 1756 // Structs can have global declarations. 1757 // Structs can have 0 fields. 1758 const Empty = struct { 1759 pub const PI = 3.14; 1760 }; 1761 test "struct namespaced variable" { 1762 assert(Empty.PI == 3.14); 1763 assert(@sizeOf(Empty) == 0); 1764 1765 // you can still instantiate an empty struct 1766 const does_nothing = Empty {}; 1767 } 1768 1769 // struct field order is determined by the compiler for optimal performance. 1770 // however, you can still calculate a struct base pointer given a field pointer: 1771 fn setYBasedOnX(x: *f32, y: f32) void { 1772 const point = @fieldParentPtr(Point, "x", x); 1773 point.y = y; 1774 } 1775 test "field parent pointer" { 1776 var point = Point { 1777 .x = 0.1234, 1778 .y = 0.5678, 1779 }; 1780 setYBasedOnX(&point.x, 0.9); 1781 assert(point.y == 0.9); 1782 } 1783 1784 // You can return a struct from a function. This is how we do generics 1785 // in Zig: 1786 fn LinkedList(comptime T: type) type { 1787 return struct { 1788 pub const Node = struct { 1789 prev: ?*Node, 1790 next: ?*Node, 1791 data: T, 1792 }; 1793 1794 first: ?*Node, 1795 last: ?*Node, 1796 len: usize, 1797 }; 1798 } 1799 1800 test "linked list" { 1801 // Functions called at compile-time are memoized. This means you can 1802 // do this: 1803 assert(LinkedList(i32) == LinkedList(i32)); 1804 1805 var list = LinkedList(i32) { 1806 .first = null, 1807 .last = null, 1808 .len = 0, 1809 }; 1810 assert(list.len == 0); 1811 1812 // Since types are first class values you can instantiate the type 1813 // by assigning it to a variable: 1814 const ListOfInts = LinkedList(i32); 1815 assert(ListOfInts == LinkedList(i32)); 1816 1817 var node = ListOfInts.Node { 1818 .prev = null, 1819 .next = null, 1820 .data = 1234, 1821 }; 1822 var list2 = LinkedList(i32) { 1823 .first = &node, 1824 .last = &node, 1825 .len = 1, 1826 }; 1827 assert((??list2.first).data == 1234); 1828 } 1829 {#code_end#} 1830 {#see_also|comptime|@fieldParentPtr#} 1831 {#header_close#} 1832 {#header_open|enum#} 1833 {#code_begin|test|enums#} 1834 const assert = @import("std").debug.assert; 1835 const mem = @import("std").mem; 1836 1837 // Declare an enum. 1838 const Type = enum { 1839 Ok, 1840 NotOk, 1841 }; 1842 1843 // Declare a specific instance of the enum variant. 1844 const c = Type.Ok; 1845 1846 // If you want access to the ordinal value of an enum, you 1847 // can specify the tag type. 1848 const Value = enum(u2) { 1849 Zero, 1850 One, 1851 Two, 1852 }; 1853 1854 // Now you can cast between u2 and Value. 1855 // The ordinal value starts from 0, counting up for each member. 1856 test "enum ordinal value" { 1857 assert(u2(Value.Zero) == 0); 1858 assert(u2(Value.One) == 1); 1859 assert(u2(Value.Two) == 2); 1860 } 1861 1862 // You can override the ordinal value for an enum. 1863 const Value2 = enum(u32) { 1864 Hundred = 100, 1865 Thousand = 1000, 1866 Million = 1000000, 1867 }; 1868 test "set enum ordinal value" { 1869 assert(u32(Value2.Hundred) == 100); 1870 assert(u32(Value2.Thousand) == 1000); 1871 assert(u32(Value2.Million) == 1000000); 1872 } 1873 1874 // Enums can have methods, the same as structs and unions. 1875 // Enum methods are not special, they are only namespaced 1876 // functions that you can call with dot syntax. 1877 const Suit = enum { 1878 Clubs, 1879 Spades, 1880 Diamonds, 1881 Hearts, 1882 1883 pub fn isClubs(self: Suit) bool { 1884 return self == Suit.Clubs; 1885 } 1886 }; 1887 test "enum method" { 1888 const p = Suit.Spades; 1889 assert(!p.isClubs()); 1890 } 1891 1892 // An enum variant of different types can be switched upon. 1893 const Foo = enum { 1894 String, 1895 Number, 1896 None, 1897 }; 1898 test "enum variant switch" { 1899 const p = Foo.Number; 1900 const what_is_it = switch (p) { 1901 Foo.String => "this is a string", 1902 Foo.Number => "this is a number", 1903 Foo.None => "this is a none", 1904 }; 1905 assert(mem.eql(u8, what_is_it, "this is a number")); 1906 } 1907 1908 // @TagType can be used to access the integer tag type of an enum. 1909 const Small = enum { 1910 One, 1911 Two, 1912 Three, 1913 Four, 1914 }; 1915 test "@TagType" { 1916 assert(@TagType(Small) == u2); 1917 } 1918 1919 // @memberCount tells how many fields an enum has: 1920 test "@memberCount" { 1921 assert(@memberCount(Small) == 4); 1922 } 1923 1924 // @memberName tells the name of a field in an enum: 1925 test "@memberName" { 1926 assert(mem.eql(u8, @memberName(Small, 1), "Two")); 1927 } 1928 1929 // @tagName gives a []const u8 representation of an enum value: 1930 test "@tagName" { 1931 assert(mem.eql(u8, @tagName(Small.Three), "Three")); 1932 } 1933 {#code_end#} 1934 {#header_open|extern enum#} 1935 <p> 1936 By default, enums are not guaranteed to be compatible with the C ABI: 1937 </p> 1938 {#code_begin|obj_err|parameter of type 'Foo' not allowed in function with calling convention 'ccc'#} 1939 const Foo = enum { A, B, C }; 1940 export fn entry(foo: Foo) void { } 1941 {#code_end#} 1942 <p> 1943 For a C-ABI-compatible enum, use <code class="zig">extern enum</code>: 1944 </p> 1945 {#code_begin|obj#} 1946 const Foo = extern enum { A, B, C }; 1947 export fn entry(foo: Foo) void { } 1948 {#code_end#} 1949 {#header_close#} 1950 {#header_open|packed enum#} 1951 <p>By default, the size of enums is not guaranteed.</p> 1952 <p><code>packed enum</code> causes the size of the enum to be the same as the size of the integer tag type 1953 of the enum:</p> 1954 {#code_begin|test#} 1955 const std = @import("std"); 1956 1957 test "packed enum" { 1958 const Number = packed enum(u8) { 1959 One, 1960 Two, 1961 Three, 1962 }; 1963 std.debug.assert(@sizeOf(Number) == @sizeOf(u8)); 1964 } 1965 {#code_end#} 1966 {#header_close#} 1967 {#see_also|@memberName|@memberCount|@tagName|@sizeOf#} 1968 {#header_close#} 1969 {#header_open|union#} 1970 {#code_begin|test|union#} 1971 const assert = @import("std").debug.assert; 1972 const mem = @import("std").mem; 1973 1974 // A union has only 1 active field at a time. 1975 const Payload = union { 1976 Int: i64, 1977 Float: f64, 1978 Bool: bool, 1979 }; 1980 test "simple union" { 1981 var payload = Payload {.Int = 1234}; 1982 // payload.Float = 12.34; // ERROR! field not active 1983 assert(payload.Int == 1234); 1984 // You can activate another field by assigning the entire union. 1985 payload = Payload {.Float = 12.34}; 1986 assert(payload.Float == 12.34); 1987 } 1988 1989 // Unions can be given an enum tag type: 1990 const ComplexTypeTag = enum { Ok, NotOk }; 1991 const ComplexType = union(ComplexTypeTag) { 1992 Ok: u8, 1993 NotOk: void, 1994 }; 1995 1996 // Declare a specific instance of the union variant. 1997 test "declare union value" { 1998 const c = ComplexType { .Ok = 0 }; 1999 assert(ComplexTypeTag(c) == ComplexTypeTag.Ok); 2000 } 2001 2002 // @TagType can be used to access the enum tag type of a union. 2003 test "@TagType" { 2004 assert(@TagType(ComplexType) == ComplexTypeTag); 2005 } 2006 2007 // Unions can be made to infer the enum tag type. 2008 const Foo = union(enum) { 2009 String: []const u8, 2010 Number: u64, 2011 2012 // void can be omitted when inferring enum tag type. 2013 None, 2014 }; 2015 test "union variant switch" { 2016 const p = Foo { .Number = 54 }; 2017 const what_is_it = switch (p) { 2018 // Capture by reference 2019 Foo.String => |*x| blk: { 2020 break :blk "this is a string"; 2021 }, 2022 2023 // Capture by value 2024 Foo.Number => |x| blk: { 2025 assert(x == 54); 2026 break :blk "this is a number"; 2027 }, 2028 2029 Foo.None => blk: { 2030 break :blk "this is a none"; 2031 }, 2032 }; 2033 assert(mem.eql(u8, what_is_it, "this is a number")); 2034 } 2035 2036 // Unions can have methods just like structs and enums: 2037 2038 const Variant = union(enum) { 2039 Int: i32, 2040 Bool: bool, 2041 2042 fn truthy(self: *const Variant) bool { 2043 return switch (self.*) { 2044 Variant.Int => |x_int| x_int != 0, 2045 Variant.Bool => |x_bool| x_bool, 2046 }; 2047 } 2048 }; 2049 2050 test "union method" { 2051 var v1 = Variant { .Int = 1 }; 2052 var v2 = Variant { .Bool = false }; 2053 2054 assert(v1.truthy()); 2055 assert(!v2.truthy()); 2056 } 2057 2058 2059 const Small = union { 2060 A: i32, 2061 B: bool, 2062 C: u8, 2063 }; 2064 2065 // @memberCount tells how many fields a union has: 2066 test "@memberCount" { 2067 assert(@memberCount(Small) == 3); 2068 } 2069 2070 // @memberName tells the name of a field in an enum: 2071 test "@memberName" { 2072 assert(mem.eql(u8, @memberName(Small, 1), "B")); 2073 } 2074 2075 // @tagName gives a []const u8 representation of an enum value, 2076 // but only if the union has an enum tag type. 2077 const Small2 = union(enum) { 2078 A: i32, 2079 B: bool, 2080 C: u8, 2081 }; 2082 test "@tagName" { 2083 assert(mem.eql(u8, @tagName(Small2.C), "C")); 2084 } 2085 {#code_end#} 2086 <p> 2087 Unions with an enum tag are generated as a struct with a tag field and union field. Zig 2088 sorts the order of the tag and union field by the largest alignment. 2089 </p> 2090 {#header_close#} 2091 {#header_open|switch#} 2092 {#code_begin|test|switch#} 2093 const assert = @import("std").debug.assert; 2094 const builtin = @import("builtin"); 2095 2096 test "switch simple" { 2097 const a: u64 = 10; 2098 const zz: u64 = 103; 2099 2100 // All branches of a switch expression must be able to be coerced to a 2101 // common type. 2102 // 2103 // Branches cannot fallthrough. If fallthrough behavior is desired, combine 2104 // the cases and use an if. 2105 const b = switch (a) { 2106 // Multiple cases can be combined via a ',' 2107 1, 2, 3 => 0, 2108 2109 // Ranges can be specified using the ... syntax. These are inclusive 2110 // both ends. 2111 5 ... 100 => 1, 2112 2113 // Branches can be arbitrarily complex. 2114 101 => blk: { 2115 const c: u64 = 5; 2116 break :blk c * 2 + 1; 2117 }, 2118 2119 // Switching on arbitrary expressions is allowed as long as the 2120 // expression is known at compile-time. 2121 zz => zz, 2122 comptime blk: { 2123 const d: u32 = 5; 2124 const e: u32 = 100; 2125 break :blk d + e; 2126 } => 107, 2127 2128 // The else branch catches everything not already captured. 2129 // Else branches are mandatory unless the entire range of values 2130 // is handled. 2131 else => 9, 2132 }; 2133 2134 assert(b == 1); 2135 } 2136 2137 test "switch enum" { 2138 const Item = union(enum) { 2139 A: u32, 2140 C: struct { x: u8, y: u8 }, 2141 D, 2142 }; 2143 2144 var a = Item { .A = 3 }; 2145 2146 // Switching on more complex enums is allowed. 2147 const b = switch (a) { 2148 // A capture group is allowed on a match, and will return the enum 2149 // value matched. 2150 Item.A => |item| item, 2151 2152 // A reference to the matched value can be obtained using `*` syntax. 2153 Item.C => |*item| blk: { 2154 item.*.x += 1; 2155 break :blk 6; 2156 }, 2157 2158 // No else is required if the types cases was exhaustively handled 2159 Item.D => 8, 2160 }; 2161 2162 assert(b == 3); 2163 } 2164 2165 // Switch expressions can be used outside a function: 2166 const os_msg = switch (builtin.os) { 2167 builtin.Os.linux => "we found a linux user", 2168 else => "not a linux user", 2169 }; 2170 2171 // Inside a function, switch statements implicitly are compile-time 2172 // evaluated if the target expression is compile-time known. 2173 test "switch inside function" { 2174 switch (builtin.os) { 2175 builtin.Os.fuchsia => { 2176 // On an OS other than fuchsia, block is not even analyzed, 2177 // so this compile error is not triggered. 2178 // On fuchsia this compile error would be triggered. 2179 @compileError("windows not supported"); 2180 }, 2181 else => {}, 2182 } 2183 } 2184 {#code_end#} 2185 {#see_also|comptime|enum|@compileError|Compile Variables#} 2186 {#header_close#} 2187 {#header_open|while#} 2188 {#code_begin|test|while#} 2189 const assert = @import("std").debug.assert; 2190 2191 test "while basic" { 2192 // A while loop is used to repeatedly execute an expression until 2193 // some condition is no longer true. 2194 var i: usize = 0; 2195 while (i < 10) { 2196 i += 1; 2197 } 2198 assert(i == 10); 2199 } 2200 2201 test "while break" { 2202 // You can use break to exit a while loop early. 2203 var i: usize = 0; 2204 while (true) { 2205 if (i == 10) 2206 break; 2207 i += 1; 2208 } 2209 assert(i == 10); 2210 } 2211 2212 test "while continue" { 2213 // You can use continue to jump back to the beginning of the loop. 2214 var i: usize = 0; 2215 while (true) { 2216 i += 1; 2217 if (i < 10) 2218 continue; 2219 break; 2220 } 2221 assert(i == 10); 2222 } 2223 2224 test "while loop continuation expression" { 2225 // You can give an expression to the while loop to execute when 2226 // the loop is continued. This is respected by the continue control flow. 2227 var i: usize = 0; 2228 while (i < 10) : (i += 1) {} 2229 assert(i == 10); 2230 } 2231 2232 test "while loop continuation expression, more complicated" { 2233 // More complex blocks can be used as an expression in the loop continue 2234 // expression. 2235 var i1: usize = 1; 2236 var j1: usize = 1; 2237 while (i1 * j1 < 2000) : ({ i1 *= 2; j1 *= 3; }) { 2238 const my_ij1 = i1 * j1; 2239 assert(my_ij1 < 2000); 2240 } 2241 } 2242 2243 test "while else" { 2244 assert(rangeHasNumber(0, 10, 5)); 2245 assert(!rangeHasNumber(0, 10, 15)); 2246 } 2247 2248 fn rangeHasNumber(begin: usize, end: usize, number: usize) bool { 2249 var i = begin; 2250 // While loops are expressions. The result of the expression is the 2251 // result of the else clause of a while loop, which is executed when 2252 // the condition of the while loop is tested as false. 2253 return while (i < end) : (i += 1) { 2254 if (i == number) { 2255 // break expressions, like return expressions, accept a value 2256 // parameter. This is the result of the while expression. 2257 // When you break from a while loop, the else branch is not 2258 // evaluated. 2259 break true; 2260 } 2261 } else false; 2262 } 2263 2264 test "while null capture" { 2265 // Just like if expressions, while loops can take a nullable as the 2266 // condition and capture the payload. When null is encountered the loop 2267 // exits. 2268 var sum1: u32 = 0; 2269 numbers_left = 3; 2270 while (eventuallyNullSequence()) |value| { 2271 sum1 += value; 2272 } 2273 assert(sum1 == 3); 2274 2275 // The else branch is allowed on nullable iteration. In this case, it will 2276 // be executed on the first null value encountered. 2277 var sum2: u32 = 0; 2278 numbers_left = 3; 2279 while (eventuallyNullSequence()) |value| { 2280 sum2 += value; 2281 } else { 2282 assert(sum1 == 3); 2283 } 2284 2285 // Just like if expressions, while loops can also take an error union as 2286 // the condition and capture the payload or the error code. When the 2287 // condition results in an error code the else branch is evaluated and 2288 // the loop is finished. 2289 var sum3: u32 = 0; 2290 numbers_left = 3; 2291 while (eventuallyErrorSequence()) |value| { 2292 sum3 += value; 2293 } else |err| { 2294 assert(err == error.ReachedZero); 2295 } 2296 } 2297 2298 var numbers_left: u32 = undefined; 2299 fn eventuallyNullSequence() ?u32 { 2300 return if (numbers_left == 0) null else blk: { 2301 numbers_left -= 1; 2302 break :blk numbers_left; 2303 }; 2304 } 2305 2306 fn eventuallyErrorSequence() error!u32 { 2307 return if (numbers_left == 0) error.ReachedZero else blk: { 2308 numbers_left -= 1; 2309 break :blk numbers_left; 2310 }; 2311 } 2312 2313 test "inline while loop" { 2314 // While loops can be inlined. This causes the loop to be unrolled, which 2315 // allows the code to do some things which only work at compile time, 2316 // such as use types as first class values. 2317 comptime var i = 0; 2318 var sum: usize = 0; 2319 inline while (i < 3) : (i += 1) { 2320 const T = switch (i) { 2321 0 => f32, 2322 1 => i8, 2323 2 => bool, 2324 else => unreachable, 2325 }; 2326 sum += typeNameLength(T); 2327 } 2328 assert(sum == 9); 2329 } 2330 2331 fn typeNameLength(comptime T: type) usize { 2332 return @typeName(T).len; 2333 } 2334 {#code_end#} 2335 {#see_also|if|Nullables|Errors|comptime|unreachable#} 2336 {#header_close#} 2337 {#header_open|for#} 2338 {#code_begin|test|for#} 2339 const assert = @import("std").debug.assert; 2340 2341 test "for basics" { 2342 const items = []i32 { 4, 5, 3, 4, 0 }; 2343 var sum: i32 = 0; 2344 2345 // For loops iterate over slices and arrays. 2346 for (items) |value| { 2347 // Break and continue are supported. 2348 if (value == 0) { 2349 continue; 2350 } 2351 sum += value; 2352 } 2353 assert(sum == 16); 2354 2355 // To iterate over a portion of a slice, reslice. 2356 for (items[0..1]) |value| { 2357 sum += value; 2358 } 2359 assert(sum == 20); 2360 2361 // To access the index of iteration, specify a second capture value. 2362 // This is zero-indexed. 2363 var sum2: i32 = 0; 2364 for (items) |value, i| { 2365 assert(@typeOf(i) == usize); 2366 sum2 += i32(i); 2367 } 2368 assert(sum2 == 10); 2369 } 2370 2371 test "for reference" { 2372 var items = []i32 { 3, 4, 2 }; 2373 2374 // Iterate over the slice by reference by 2375 // specifying that the capture value is a pointer. 2376 for (items) |*value| { 2377 value.* += 1; 2378 } 2379 2380 assert(items[0] == 4); 2381 assert(items[1] == 5); 2382 assert(items[2] == 3); 2383 } 2384 2385 test "for else" { 2386 // For allows an else attached to it, the same as a while loop. 2387 var items = []?i32 { 3, 4, null, 5 }; 2388 2389 // For loops can also be used as expressions. 2390 var sum: i32 = 0; 2391 const result = for (items) |value| { 2392 if (value == null) { 2393 break 9; 2394 } else { 2395 sum += ??value; 2396 } 2397 } else blk: { 2398 assert(sum == 7); 2399 break :blk sum; 2400 }; 2401 } 2402 2403 2404 test "inline for loop" { 2405 const nums = []i32{2, 4, 6}; 2406 // For loops can be inlined. This causes the loop to be unrolled, which 2407 // allows the code to do some things which only work at compile time, 2408 // such as use types as first class values. 2409 // The capture value and iterator value of inlined for loops are 2410 // compile-time known. 2411 var sum: usize = 0; 2412 inline for (nums) |i| { 2413 const T = switch (i) { 2414 2 => f32, 2415 4 => i8, 2416 6 => bool, 2417 else => unreachable, 2418 }; 2419 sum += typeNameLength(T); 2420 } 2421 assert(sum == 9); 2422 } 2423 2424 fn typeNameLength(comptime T: type) usize { 2425 return @typeName(T).len; 2426 } 2427 {#code_end#} 2428 {#see_also|while|comptime|Arrays|Slices#} 2429 {#header_close#} 2430 {#header_open|if#} 2431 {#code_begin|test|if#} 2432 // If expressions have three uses, corresponding to the three types: 2433 // * bool 2434 // * ?T 2435 // * error!T 2436 2437 const assert = @import("std").debug.assert; 2438 2439 test "if boolean" { 2440 // If expressions test boolean conditions. 2441 const a: u32 = 5; 2442 const b: u32 = 4; 2443 if (a != b) { 2444 assert(true); 2445 } else if (a == 9) { 2446 unreachable; 2447 } else { 2448 unreachable; 2449 } 2450 2451 // If expressions are used instead of a ternary expression. 2452 const result = if (a != b) 47 else 3089; 2453 assert(result == 47); 2454 } 2455 2456 test "if nullable" { 2457 // If expressions test for null. 2458 2459 const a: ?u32 = 0; 2460 if (a) |value| { 2461 assert(value == 0); 2462 } else { 2463 unreachable; 2464 } 2465 2466 const b: ?u32 = null; 2467 if (b) |value| { 2468 unreachable; 2469 } else { 2470 assert(true); 2471 } 2472 2473 // The else is not required. 2474 if (a) |value| { 2475 assert(value == 0); 2476 } 2477 2478 // To test against null only, use the binary equality operator. 2479 if (b == null) { 2480 assert(true); 2481 } 2482 2483 // Access the value by reference using a pointer capture. 2484 var c: ?u32 = 3; 2485 if (c) |*value| { 2486 value.* = 2; 2487 } 2488 2489 if (c) |value| { 2490 assert(value == 2); 2491 } else { 2492 unreachable; 2493 } 2494 } 2495 2496 test "if error union" { 2497 // If expressions test for errors. 2498 // Note the |err| capture on the else. 2499 2500 const a: error!u32 = 0; 2501 if (a) |value| { 2502 assert(value == 0); 2503 } else |err| { 2504 unreachable; 2505 } 2506 2507 const b: error!u32 = error.BadValue; 2508 if (b) |value| { 2509 unreachable; 2510 } else |err| { 2511 assert(err == error.BadValue); 2512 } 2513 2514 // The else and |err| capture is strictly required. 2515 if (a) |value| { 2516 assert(value == 0); 2517 } else |_| {} 2518 2519 // To check only the error value, use an empty block expression. 2520 if (b) |_| {} else |err| { 2521 assert(err == error.BadValue); 2522 } 2523 2524 // Access the value by reference using a pointer capture. 2525 var c: error!u32 = 3; 2526 if (c) |*value| { 2527 value.* = 9; 2528 } else |err| { 2529 unreachable; 2530 } 2531 2532 if (c) |value| { 2533 assert(value == 9); 2534 } else |err| { 2535 unreachable; 2536 } 2537 } 2538 {#code_end#} 2539 {#see_also|Nullables|Errors#} 2540 {#header_close#} 2541 {#header_open|defer#} 2542 {#code_begin|test|defer#} 2543 const std = @import("std"); 2544 const assert = std.debug.assert; 2545 const warn = std.debug.warn; 2546 2547 // defer will execute an expression at the end of the current scope. 2548 fn deferExample() usize { 2549 var a: usize = 1; 2550 2551 { 2552 defer a = 2; 2553 a = 1; 2554 } 2555 assert(a == 2); 2556 2557 a = 5; 2558 return a; 2559 } 2560 2561 test "defer basics" { 2562 assert(deferExample() == 5); 2563 } 2564 2565 // If multiple defer statements are specified, they will be executed in 2566 // the reverse order they were run. 2567 fn deferUnwindExample() void { 2568 warn("\n"); 2569 2570 defer { 2571 warn("1 "); 2572 } 2573 defer { 2574 warn("2 "); 2575 } 2576 if (false) { 2577 // defers are not run if they are never executed. 2578 defer { 2579 warn("3 "); 2580 } 2581 } 2582 } 2583 2584 test "defer unwinding" { 2585 deferUnwindExample(); 2586 } 2587 2588 // The errdefer keyword is similar to defer, but will only execute if the 2589 // scope returns with an error. 2590 // 2591 // This is especially useful in allowing a function to clean up properly 2592 // on error, and replaces goto error handling tactics as seen in c. 2593 fn deferErrorExample(is_error: bool) !void { 2594 warn("\nstart of function\n"); 2595 2596 // This will always be executed on exit 2597 defer { 2598 warn("end of function\n"); 2599 } 2600 2601 errdefer { 2602 warn("encountered an error!\n"); 2603 } 2604 2605 if (is_error) { 2606 return error.DeferError; 2607 } 2608 } 2609 2610 test "errdefer unwinding" { 2611 _ = deferErrorExample(false); 2612 _ = deferErrorExample(true); 2613 } 2614 {#code_end#} 2615 {#see_also|Errors#} 2616 {#header_close#} 2617 {#header_open|unreachable#} 2618 <p> 2619 In <code>Debug</code> and <code>ReleaseSafe</code> mode, and when using <code>zig test</code>, 2620 <code>unreachable</code> emits a call to <code>panic</code> with the message <code>reached unreachable code</code>. 2621 </p> 2622 <p> 2623 In <code>ReleaseFast</code> mode, the optimizer uses the assumption that <code>unreachable</code> code 2624 will never be hit to perform optimizations. However, <code>zig test</code> even in <code>ReleaseFast</code> mode 2625 still emits <code>unreachable</code> as calls to <code>panic</code>. 2626 </p> 2627 {#header_open|Basics#} 2628 {#code_begin|test#} 2629 // unreachable is used to assert that control flow will never happen upon a 2630 // particular location: 2631 test "basic math" { 2632 const x = 1; 2633 const y = 2; 2634 if (x + y != 3) { 2635 unreachable; 2636 } 2637 } 2638 {#code_end#} 2639 <p>In fact, this is how assert is implemented:</p> 2640 {#code_begin|test_err#} 2641 fn assert(ok: bool) void { 2642 if (!ok) unreachable; // assertion failure 2643 } 2644 2645 // This test will fail because we hit unreachable. 2646 test "this will fail" { 2647 assert(false); 2648 } 2649 {#code_end#} 2650 {#header_close#} 2651 {#header_open|At Compile-Time#} 2652 {#code_begin|test_err|unreachable code#} 2653 const assert = @import("std").debug.assert; 2654 2655 test "type of unreachable" { 2656 comptime { 2657 // The type of unreachable is noreturn. 2658 2659 // However this assertion will still fail because 2660 // evaluating unreachable at compile-time is a compile error. 2661 2662 assert(@typeOf(unreachable) == noreturn); 2663 } 2664 } 2665 {#code_end#} 2666 {#see_also|Zig Test|Build Mode|comptime#} 2667 {#header_close#} 2668 {#header_close#} 2669 {#header_open|noreturn#} 2670 <p> 2671 <code>noreturn</code> is the type of: 2672 </p> 2673 <ul> 2674 <li><code>break</code></li> 2675 <li><code>continue</code></li> 2676 <li><code>return</code></li> 2677 <li><code>unreachable</code></li> 2678 <li><code>while (true) {}</code></li> 2679 </ul> 2680 <p>When resolving types together, such as <code>if</code> clauses or <code>switch</code> prongs, 2681 the <code>noreturn</code> type is compatible with every other type. Consider: 2682 </p> 2683 {#code_begin|test#} 2684 fn foo(condition: bool, b: u32) void { 2685 const a = if (condition) b else return; 2686 @panic("do something with a"); 2687 } 2688 test "noreturn" { 2689 foo(false, 1); 2690 } 2691 {#code_end#} 2692 <p>Another use case for <code>noreturn</code> is the <code>exit</code> function:</p> 2693 {#code_begin|test#} 2694 {#target_windows#} 2695 pub extern "kernel32" stdcallcc fn ExitProcess(exit_code: c_uint) noreturn; 2696 2697 test "foo" { 2698 const value = bar() catch ExitProcess(1); 2699 assert(value == 1234); 2700 } 2701 2702 fn bar() error!u32 { 2703 return 1234; 2704 } 2705 2706 const assert = @import("std").debug.assert; 2707 {#code_end#} 2708 {#header_close#} 2709 {#header_open|Functions#} 2710 {#code_begin|test|functions#} 2711 const assert = @import("std").debug.assert; 2712 2713 // Functions are declared like this 2714 fn add(a: i8, b: i8) i8 { 2715 if (a == 0) { 2716 // You can still return manually if needed. 2717 return b; 2718 } 2719 2720 return a + b; 2721 } 2722 2723 // The export specifier makes a function externally visible in the generated 2724 // object file, and makes it use the C ABI. 2725 export fn sub(a: i8, b: i8) i8 { return a - b; } 2726 2727 // The extern specifier is used to declare a function that will be resolved 2728 // at link time, when linking statically, or at runtime, when linking 2729 // dynamically. 2730 // The stdcallcc specifier changes the calling convention of the function. 2731 extern "kernel32" stdcallcc fn ExitProcess(exit_code: u32) noreturn; 2732 extern "c" fn atan2(a: f64, b: f64) f64; 2733 2734 // The @setCold builtin tells the optimizer that a function is rarely called. 2735 fn abort() noreturn { 2736 @setCold(true); 2737 while (true) {} 2738 } 2739 2740 // nakedcc makes a function not have any function prologue or epilogue. 2741 // This can be useful when integrating with assembly. 2742 nakedcc fn _start() noreturn { 2743 abort(); 2744 } 2745 2746 // The pub specifier allows the function to be visible when importing. 2747 // Another file can use @import and call sub2 2748 pub fn sub2(a: i8, b: i8) i8 { return a - b; } 2749 2750 // Functions can be used as values and are equivalent to pointers. 2751 const call2_op = fn (a: i8, b: i8) i8; 2752 fn do_op(fn_call: call2_op, op1: i8, op2: i8) i8 { 2753 return fn_call(op1, op2); 2754 } 2755 2756 test "function" { 2757 assert(do_op(add, 5, 6) == 11); 2758 assert(do_op(sub2, 5, 6) == -1); 2759 } 2760 {#code_end#} 2761 <p>Function values are like pointers:</p> 2762 {#code_begin|obj#} 2763 const assert = @import("std").debug.assert; 2764 2765 comptime { 2766 assert(@typeOf(foo) == fn()void); 2767 assert(@sizeOf(fn()void) == @sizeOf(?fn()void)); 2768 } 2769 2770 fn foo() void { } 2771 {#code_end#} 2772 {#header_open|Pass-by-value Parameters#} 2773 <p> 2774 In Zig, structs, unions, and enums with payloads cannot be passed by value 2775 to a function. 2776 </p> 2777 {#code_begin|test_err|not copyable; cannot pass by value#} 2778 const Foo = struct { 2779 x: i32, 2780 }; 2781 2782 fn bar(foo: Foo) void {} 2783 2784 test "pass aggregate type by value to function" { 2785 bar(Foo {.x = 12,}); 2786 } 2787 {#code_end#} 2788 <p> 2789 Instead, one must use <code>*const</code>. Zig allows implicitly casting something 2790 to a const pointer to it: 2791 </p> 2792 {#code_begin|test#} 2793 const Foo = struct { 2794 x: i32, 2795 }; 2796 2797 fn bar(foo: *const Foo) void {} 2798 2799 test "implicitly cast to const pointer" { 2800 bar(Foo {.x = 12,}); 2801 } 2802 {#code_end#} 2803 <p> 2804 However, 2805 the C ABI does allow passing structs and unions by value. So functions which 2806 use the C calling convention may pass structs and unions by value. 2807 </p> 2808 {#header_close#} 2809 {#header_open|Function Reflection#} 2810 {#code_begin|test#} 2811 const assert = @import("std").debug.assert; 2812 2813 test "fn reflection" { 2814 assert(@typeOf(assert).ReturnType == void); 2815 assert(@typeOf(assert).is_var_args == false); 2816 } 2817 {#code_end#} 2818 {#header_close#} 2819 {#header_close#} 2820 {#header_open|Errors#} 2821 {#header_open|Error Set Type#} 2822 <p> 2823 An error set is like an {#link|enum#}. 2824 However, each error name across the entire compilation gets assigned an unsigned integer 2825 greater than 0. You are allowed to declare the same error name more than once, and if you do, it 2826 gets assigned the same integer value. 2827 </p> 2828 <p> 2829 The number of unique error values across the entire compilation should determine the size of the error set type. 2830 However right now it is hard coded to be a <code>u16</code>. See <a href="https://github.com/ziglang/zig/issues/786">#768</a>. 2831 </p> 2832 <p> 2833 You can implicitly cast an error from a subset to its superset: 2834 </p> 2835 {#code_begin|test#} 2836 const std = @import("std"); 2837 2838 const FileOpenError = error { 2839 AccessDenied, 2840 OutOfMemory, 2841 FileNotFound, 2842 }; 2843 2844 const AllocationError = error { 2845 OutOfMemory, 2846 }; 2847 2848 test "implicit cast subset to superset" { 2849 const err = foo(AllocationError.OutOfMemory); 2850 std.debug.assert(err == FileOpenError.OutOfMemory); 2851 } 2852 2853 fn foo(err: AllocationError) FileOpenError { 2854 return err; 2855 } 2856 {#code_end#} 2857 <p> 2858 But you cannot implicitly cast an error from a superset to a subset: 2859 </p> 2860 {#code_begin|test_err|not a member of destination error set#} 2861 const FileOpenError = error { 2862 AccessDenied, 2863 OutOfMemory, 2864 FileNotFound, 2865 }; 2866 2867 const AllocationError = error { 2868 OutOfMemory, 2869 }; 2870 2871 test "implicit cast superset to subset" { 2872 foo(FileOpenError.OutOfMemory) catch {}; 2873 } 2874 2875 fn foo(err: FileOpenError) AllocationError { 2876 return err; 2877 } 2878 {#code_end#} 2879 <p> 2880 There is a shortcut for declaring an error set with only 1 value, and then getting that value: 2881 </p> 2882 {#code_begin|syntax#} 2883 const err = error.FileNotFound; 2884 {#code_end#} 2885 <p>This is equivalent to:</p> 2886 {#code_begin|syntax#} 2887 const err = (error {FileNotFound}).FileNotFound; 2888 {#code_end#} 2889 <p> 2890 This becomes useful when using {#link|Inferred Error Sets#}. 2891 </p> 2892 {#header_open|The Global Error Set#} 2893 <p><code>error</code> refers to the global error set. 2894 This is the error set that contains all errors in the entire compilation unit. 2895 It is a superset of all other error sets and a subset of none of them. 2896 </p> 2897 <p> 2898 You can implicitly cast any error set to the global one, and you can explicitly 2899 cast an error of global error set to a non-global one. This inserts a language-level 2900 assert to make sure the error value is in fact in the destination error set. 2901 </p> 2902 <p> 2903 The global error set should generally be avoided because it prevents the 2904 compiler from knowing what errors are possible at compile-time. Knowing 2905 the error set at compile-time is better for generated documentation and 2906 helpful error messages, such as forgetting a possible error value in a {#link|switch#}. 2907 </p> 2908 {#header_close#} 2909 {#header_close#} 2910 {#header_open|Error Union Type#} 2911 <p> 2912 An error set type and normal type can be combined with the <code>!</code> 2913 binary operator to form an error union type. You are likely to use an 2914 error union type more often than an error set type by itself. 2915 </p> 2916 <p> 2917 Here is a function to parse a string into a 64-bit integer: 2918 </p> 2919 {#code_begin|test#} 2920 pub fn parseU64(buf: []const u8, radix: u8) !u64 { 2921 var x: u64 = 0; 2922 2923 for (buf) |c| { 2924 const digit = charToDigit(c); 2925 2926 if (digit >= radix) { 2927 return error.InvalidChar; 2928 } 2929 2930 // x *= radix 2931 if (@mulWithOverflow(u64, x, radix, &x)) { 2932 return error.Overflow; 2933 } 2934 2935 // x += digit 2936 if (@addWithOverflow(u64, x, digit, &x)) { 2937 return error.Overflow; 2938 } 2939 } 2940 2941 return x; 2942 } 2943 2944 fn charToDigit(c: u8) u8 { 2945 return switch (c) { 2946 '0' ... '9' => c - '0', 2947 'A' ... 'Z' => c - 'A' + 10, 2948 'a' ... 'z' => c - 'a' + 10, 2949 else => @maxValue(u8), 2950 }; 2951 } 2952 2953 test "parse u64" { 2954 const result = try parseU64("1234", 10); 2955 @import("std").debug.assert(result == 1234); 2956 } 2957 {#code_end#} 2958 <p> 2959 Notice the return type is <code>!u64</code>. This means that the function 2960 either returns an unsigned 64 bit integer, or an error. We left off the error set 2961 to the left of the <code>!</code>, so the error set is inferred. 2962 </p> 2963 <p> 2964 Within the function definition, you can see some return statements that return 2965 an error, and at the bottom a return statement that returns a <code>u64</code>. 2966 Both types implicitly cast to <code>error!u64</code>. 2967 </p> 2968 <p> 2969 What it looks like to use this function varies depending on what you're 2970 trying to do. One of the following: 2971 </p> 2972 <ul> 2973 <li>You want to provide a default value if it returned an error.</li> 2974 <li>If it returned an error then you want to return the same error.</li> 2975 <li>You know with complete certainty it will not return an error, so want to unconditionally unwrap it.</li> 2976 <li>You want to take a different action for each possible error.</li> 2977 </ul> 2978 <p>If you want to provide a default value, you can use the <code>catch</code> binary operator:</p> 2979 {#code_begin|syntax#} 2980 fn doAThing(str: []u8) void { 2981 const number = parseU64(str, 10) catch 13; 2982 // ... 2983 } 2984 {#code_end#} 2985 <p> 2986 In this code, <code>number</code> will be equal to the successfully parsed string, or 2987 a default value of 13. The type of the right hand side of the binary <code>catch</code> operator must 2988 match the unwrapped error union type, or be of type <code>noreturn</code>. 2989 </p> 2990 <p>Let's say you wanted to return the error if you got one, otherwise continue with the 2991 function logic:</p> 2992 {#code_begin|syntax#} 2993 fn doAThing(str: []u8) !void { 2994 const number = parseU64(str, 10) catch |err| return err; 2995 // ... 2996 } 2997 {#code_end#} 2998 <p> 2999 There is a shortcut for this. The <code>try</code> expression: 3000 </p> 3001 {#code_begin|syntax#} 3002 fn doAThing(str: []u8) !void { 3003 const number = try parseU64(str, 10); 3004 // ... 3005 } 3006 {#code_end#} 3007 <p> 3008 <code>try</code> evaluates an error union expression. If it is an error, it returns 3009 from the current function with the same error. Otherwise, the expression results in 3010 the unwrapped value. 3011 </p> 3012 <p> 3013 Maybe you know with complete certainty that an expression will never be an error. 3014 In this case you can do this: 3015 </p> 3016 {#code_begin|syntax#}const number = parseU64("1234", 10) catch unreachable;{#code_end#} 3017 <p> 3018 Here we know for sure that "1234" will parse successfully. So we put the 3019 <code>unreachable</code> value on the right hand side. <code>unreachable</code> generates 3020 a panic in Debug and ReleaseSafe modes and undefined behavior in ReleaseFast mode. So, while we're debugging the 3021 application, if there <em>was</em> a surprise error here, the application would crash 3022 appropriately. 3023 </p> 3024 <p> 3025 Finally, you may want to take a different action for every situation. For that, we combine 3026 the <code>if</code> and <code>switch</code> expression: 3027 </p> 3028 {#code_begin|syntax#} 3029 fn doAThing(str: []u8) void { 3030 if (parseU64(str, 10)) |number| { 3031 doSomethingWithNumber(number); 3032 } else |err| switch (err) { 3033 error.Overflow => { 3034 // handle overflow... 3035 }, 3036 // we promise that InvalidChar won't happen (or crash in debug mode if it does) 3037 error.InvalidChar => unreachable, 3038 } 3039 } 3040 {#code_end#} 3041 <p> 3042 The other component to error handling is defer statements. 3043 In addition to an unconditional <code>defer</code>, Zig has <code>errdefer</code>, 3044 which evaluates the deferred expression on block exit path if and only if 3045 the function returned with an error from the block. 3046 </p> 3047 <p> 3048 Example: 3049 </p> 3050 {#code_begin|syntax#} 3051 fn createFoo(param: i32) !Foo { 3052 const foo = try tryToAllocateFoo(); 3053 // now we have allocated foo. we need to free it if the function fails. 3054 // but we want to return it if the function succeeds. 3055 errdefer deallocateFoo(foo); 3056 3057 const tmp_buf = allocateTmpBuffer() ?? return error.OutOfMemory; 3058 // tmp_buf is truly a temporary resource, and we for sure want to clean it up 3059 // before this block leaves scope 3060 defer deallocateTmpBuffer(tmp_buf); 3061 3062 if (param > 1337) return error.InvalidParam; 3063 3064 // here the errdefer will not run since we're returning success from the function. 3065 // but the defer will run! 3066 return foo; 3067 } 3068 {#code_end#} 3069 <p> 3070 The neat thing about this is that you get robust error handling without 3071 the verbosity and cognitive overhead of trying to make sure every exit path 3072 is covered. The deallocation code is always directly following the allocation code. 3073 </p> 3074 <p> 3075 A couple of other tidbits about error handling: 3076 </p> 3077 <ul> 3078 <li>These primitives give enough expressiveness that it's completely practical 3079 to have failing to check for an error be a compile error. If you really want 3080 to ignore the error, you can add <code>catch unreachable</code> and 3081 get the added benefit of crashing in Debug and ReleaseSafe modes if your assumption was wrong. 3082 </li> 3083 <li> 3084 Since Zig understands error types, it can pre-weight branches in favor of 3085 errors not occuring. Just a small optimization benefit that is not available 3086 in other languages. 3087 </li> 3088 </ul> 3089 {#see_also|defer|if|switch#} 3090 3091 <p>An error union is created with the <code>!</code> binary operator. 3092 You can use compile-time reflection to access the child type of an error union:</p> 3093 {#code_begin|test#} 3094 const assert = @import("std").debug.assert; 3095 3096 test "error union" { 3097 var foo: error!i32 = undefined; 3098 3099 // Implicitly cast from child type of an error union: 3100 foo = 1234; 3101 3102 // Implicitly cast from an error set: 3103 foo = error.SomeError; 3104 3105 // Use compile-time reflection to access the payload type of an error union: 3106 comptime assert(@typeOf(foo).Payload == i32); 3107 3108 // Use compile-time reflection to access the error set type of an error union: 3109 comptime assert(@typeOf(foo).ErrorSet == error); 3110 } 3111 {#code_end#} 3112 <p>TODO the <code>||</code> operator for error sets</p> 3113 {#header_open|Inferred Error Sets#} 3114 <p> 3115 Because many functions in Zig return a possible error, Zig supports inferring the error set. 3116 To infer the error set for a function, use this syntax: 3117 </p> 3118 {#code_begin|test#} 3119 // With an inferred error set 3120 pub fn add_inferred(comptime T: type, a: T, b: T) !T { 3121 var answer: T = undefined; 3122 return if (@addWithOverflow(T, a, b, &answer)) error.Overflow else answer; 3123 } 3124 3125 // With an explicit error set 3126 pub fn add_explicit(comptime T: type, a: T, b: T) Error!T { 3127 var answer: T = undefined; 3128 return if (@addWithOverflow(T, a, b, &answer)) error.Overflow else answer; 3129 } 3130 3131 const Error = error { 3132 Overflow, 3133 }; 3134 3135 const std = @import("std"); 3136 3137 test "inferred error set" { 3138 if (add_inferred(u8, 255, 1)) |_| unreachable else |err| switch (err) { 3139 error.Overflow => {}, // ok 3140 } 3141 } 3142 {#code_end#} 3143 <p> 3144 When a function has an inferred error set, that function becomes generic and thus it becomes 3145 trickier to do certain things with it, such as obtain a function pointer, or have an error 3146 set that is consistent across different build targets. Additionally, inferred error sets 3147 are incompatible with recursion. 3148 </p> 3149 <p> 3150 In these situations, it is recommended to use an explicit error set. You can generally start 3151 with an empty error set and let compile errors guide you toward completing the set. 3152 </p> 3153 <p> 3154 These limitations may be overcome in a future version of Zig. 3155 </p> 3156 {#header_close#} 3157 {#header_close#} 3158 {#header_open|Error Return Traces#} 3159 <p>TODO</p> 3160 {#header_close#} 3161 {#header_close#} 3162 {#header_open|Nullables#} 3163 <p> 3164 One area that Zig provides safety without compromising efficiency or 3165 readability is with the nullable type. 3166 </p> 3167 <p> 3168 The question mark symbolizes the nullable type. You can convert a type to a nullable 3169 type by putting a question mark in front of it, like this: 3170 </p> 3171 {#code_begin|syntax#} 3172 // normal integer 3173 const normal_int: i32 = 1234; 3174 3175 // nullable integer 3176 const nullable_int: ?i32 = 5678; 3177 {#code_end#} 3178 <p> 3179 Now the variable <code>nullable_int</code> could be an <code>i32</code>, or <code>null</code>. 3180 </p> 3181 <p> 3182 Instead of integers, let's talk about pointers. Null references are the source of many runtime 3183 exceptions, and even stand accused of being 3184 <a href="https://www.lucidchart.com/techblog/2015/08/31/the-worst-mistake-of-computer-science/">the worst mistake of computer science</a>. 3185 </p> 3186 <p>Zig does not have them.</p> 3187 <p> 3188 Instead, you can use a nullable pointer. This secretly compiles down to a normal pointer, 3189 since we know we can use 0 as the null value for the nullable type. But the compiler 3190 can check your work and make sure you don't assign null to something that can't be null. 3191 </p> 3192 <p> 3193 Typically the downside of not having null is that it makes the code more verbose to 3194 write. But, let's compare some equivalent C code and Zig code. 3195 </p> 3196 <p> 3197 Task: call malloc, if the result is null, return null. 3198 </p> 3199 <p>C code</p> 3200 <pre><code class="cpp">// malloc prototype included for reference 3201 void *malloc(size_t size); 3202 3203 struct Foo *do_a_thing(void) { 3204 char *ptr = malloc(1234); 3205 if (!ptr) return NULL; 3206 // ... 3207 }</code></pre> 3208 <p>Zig code</p> 3209 {#code_begin|syntax#} 3210 // malloc prototype included for reference 3211 extern fn malloc(size: size_t) ?*u8; 3212 3213 fn doAThing() ?*Foo { 3214 const ptr = malloc(1234) ?? return null; 3215 // ... 3216 } 3217 {#code_end#} 3218 <p> 3219 Here, Zig is at least as convenient, if not more, than C. And, the type of "ptr" 3220 is <code>*u8</code> <em>not</em> <code>?*u8</code>. The <code>??</code> operator 3221 unwrapped the nullable type and therefore <code>ptr</code> is guaranteed to be non-null everywhere 3222 it is used in the function. 3223 </p> 3224 <p> 3225 The other form of checking against NULL you might see looks like this: 3226 </p> 3227 <pre><code class="cpp">void do_a_thing(struct Foo *foo) { 3228 // do some stuff 3229 3230 if (foo) { 3231 do_something_with_foo(foo); 3232 } 3233 3234 // do some stuff 3235 }</code></pre> 3236 <p> 3237 In Zig you can accomplish the same thing: 3238 </p> 3239 {#code_begin|syntax#} 3240 fn doAThing(nullable_foo: ?*Foo) void { 3241 // do some stuff 3242 3243 if (nullable_foo) |foo| { 3244 doSomethingWithFoo(foo); 3245 } 3246 3247 // do some stuff 3248 } 3249 {#code_end#} 3250 <p> 3251 Once again, the notable thing here is that inside the if block, 3252 <code>foo</code> is no longer a nullable pointer, it is a pointer, which 3253 cannot be null. 3254 </p> 3255 <p> 3256 One benefit to this is that functions which take pointers as arguments can 3257 be annotated with the "nonnull" attribute - <code>__attribute__((nonnull))</code> in 3258 <a href="https://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Function-Attributes.html">GCC</a>. 3259 The optimizer can sometimes make better decisions knowing that pointer arguments 3260 cannot be null. 3261 </p> 3262 {#header_open|Nullable Type#} 3263 <p>A nullable is created by putting <code>?</code> in front of a type. You can use compile-time 3264 reflection to access the child type of a nullable:</p> 3265 {#code_begin|test#} 3266 const assert = @import("std").debug.assert; 3267 3268 test "nullable type" { 3269 // Declare a nullable and implicitly cast from null: 3270 var foo: ?i32 = null; 3271 3272 // Implicitly cast from child type of a nullable 3273 foo = 1234; 3274 3275 // Use compile-time reflection to access the child type of the nullable: 3276 comptime assert(@typeOf(foo).Child == i32); 3277 } 3278 {#code_end#} 3279 {#header_close#} 3280 {#header_close#} 3281 {#header_open|Casting#} 3282 <p>TODO: explain implicit vs explicit casting</p> 3283 <p>TODO: resolve peer types builtin</p> 3284 <p>TODO: truncate builtin</p> 3285 <p>TODO: bitcast builtin</p> 3286 <p>TODO: int to ptr builtin</p> 3287 <p>TODO: ptr to int builtin</p> 3288 <p>TODO: ptrcast builtin</p> 3289 <p>TODO: explain number literals vs concrete types</p> 3290 {#header_close#} 3291 {#header_open|void#} 3292 <p>TODO: assigning void has no codegen</p> 3293 <p>TODO: hashmap with void becomes a set</p> 3294 <p>TODO: difference between c_void and void</p> 3295 <p>TODO: void is the default return value of functions</p> 3296 <p>TODO: functions require assigning the return value</p> 3297 {#header_close#} 3298 {#header_open|this#} 3299 <p>TODO: example of this referring to Self struct</p> 3300 <p>TODO: example of this referring to recursion function</p> 3301 <p>TODO: example of this referring to basic block for @setRuntimeSafety</p> 3302 {#header_close#} 3303 {#header_open|comptime#} 3304 <p> 3305 Zig places importance on the concept of whether an expression is known at compile-time. 3306 There are a few different places this concept is used, and these building blocks are used 3307 to keep the language small, readable, and powerful. 3308 </p> 3309 {#header_open|Introducing the Compile-Time Concept#} 3310 {#header_open|Compile-Time Parameters#} 3311 <p> 3312 Compile-time parameters is how Zig implements generics. It is compile-time duck typing. 3313 </p> 3314 {#code_begin|syntax#} 3315 fn max(comptime T: type, a: T, b: T) T { 3316 return if (a > b) a else b; 3317 } 3318 fn gimmeTheBiggerFloat(a: f32, b: f32) f32 { 3319 return max(f32, a, b); 3320 } 3321 fn gimmeTheBiggerInteger(a: u64, b: u64) u64 { 3322 return max(u64, a, b); 3323 } 3324 {#code_end#} 3325 <p> 3326 In Zig, types are first-class citizens. They can be assigned to variables, passed as parameters to functions, 3327 and returned from functions. However, they can only be used in expressions which are known at <em>compile-time</em>, 3328 which is why the parameter <code>T</code> in the above snippet must be marked with <code>comptime</code>. 3329 </p> 3330 <p> 3331 A <code>comptime</code> parameter means that: 3332 </p> 3333 <ul> 3334 <li>At the callsite, the value must be known at compile-time, or it is a compile error.</li> 3335 <li>In the function definition, the value is known at compile-time.</li> 3336 </ul> 3337 <p> 3338 </p> 3339 <p> 3340 For example, if we were to introduce another function to the above snippet: 3341 </p> 3342 {#code_begin|test_err|unable to evaluate constant expression#} 3343 fn max(comptime T: type, a: T, b: T) T { 3344 return if (a > b) a else b; 3345 } 3346 test "try to pass a runtime type" { 3347 foo(false); 3348 } 3349 fn foo(condition: bool) void { 3350 const result = max( 3351 if (condition) f32 else u64, 3352 1234, 3353 5678); 3354 } 3355 {#code_end#} 3356 <p> 3357 This is an error because the programmer attempted to pass a value only known at run-time 3358 to a function which expects a value known at compile-time. 3359 </p> 3360 <p> 3361 Another way to get an error is if we pass a type that violates the type checker when the 3362 function is analyzed. This is what it means to have <em>compile-time duck typing</em>. 3363 </p> 3364 <p> 3365 For example: 3366 </p> 3367 {#code_begin|test_err|operator not allowed for type 'bool'#} 3368 fn max(comptime T: type, a: T, b: T) T { 3369 return if (a > b) a else b; 3370 } 3371 test "try to compare bools" { 3372 _ = max(bool, true, false); 3373 } 3374 {#code_end#} 3375 <p> 3376 On the flip side, inside the function definition with the <code>comptime</code> parameter, the 3377 value is known at compile-time. This means that we actually could make this work for the bool type 3378 if we wanted to: 3379 </p> 3380 {#code_begin|test#} 3381 fn max(comptime T: type, a: T, b: T) T { 3382 if (T == bool) { 3383 return a or b; 3384 } else if (a > b) { 3385 return a; 3386 } else { 3387 return b; 3388 } 3389 } 3390 test "try to compare bools" { 3391 @import("std").debug.assert(max(bool, false, true) == true); 3392 } 3393 {#code_end#} 3394 <p> 3395 This works because Zig implicitly inlines <code>if</code> expressions when the condition 3396 is known at compile-time, and the compiler guarantees that it will skip analysis of 3397 the branch not taken. 3398 </p> 3399 <p> 3400 This means that the actual function generated for <code>max</code> in this situation looks like 3401 this: 3402 </p> 3403 {#code_begin|syntax#} 3404 fn max(a: bool, b: bool) bool { 3405 return a or b; 3406 } 3407 {#code_end#} 3408 <p> 3409 All the code that dealt with compile-time known values is eliminated and we are left with only 3410 the necessary run-time code to accomplish the task. 3411 </p> 3412 <p> 3413 This works the same way for <code>switch</code> expressions - they are implicitly inlined 3414 when the target expression is compile-time known. 3415 </p> 3416 {#header_close#} 3417 {#header_open|Compile-Time Variables#} 3418 <p> 3419 In Zig, the programmer can label variables as <code>comptime</code>. This guarantees to the compiler 3420 that every load and store of the variable is performed at compile-time. Any violation of this results in a 3421 compile error. 3422 </p> 3423 <p> 3424 This combined with the fact that we can <code>inline</code> loops allows us to write 3425 a function which is partially evaluated at compile-time and partially at run-time. 3426 </p> 3427 <p> 3428 For example: 3429 </p> 3430 {#code_begin|test|comptime_vars#} 3431 const assert = @import("std").debug.assert; 3432 3433 const CmdFn = struct { 3434 name: []const u8, 3435 func: fn(i32) i32, 3436 }; 3437 3438 const cmd_fns = []CmdFn{ 3439 CmdFn {.name = "one", .func = one}, 3440 CmdFn {.name = "two", .func = two}, 3441 CmdFn {.name = "three", .func = three}, 3442 }; 3443 fn one(value: i32) i32 { return value + 1; } 3444 fn two(value: i32) i32 { return value + 2; } 3445 fn three(value: i32) i32 { return value + 3; } 3446 3447 fn performFn(comptime prefix_char: u8, start_value: i32) i32 { 3448 var result: i32 = start_value; 3449 comptime var i = 0; 3450 inline while (i < cmd_fns.len) : (i += 1) { 3451 if (cmd_fns[i].name[0] == prefix_char) { 3452 result = cmd_fns[i].func(result); 3453 } 3454 } 3455 return result; 3456 } 3457 3458 test "perform fn" { 3459 assert(performFn('t', 1) == 6); 3460 assert(performFn('o', 0) == 1); 3461 assert(performFn('w', 99) == 99); 3462 } 3463 {#code_end#} 3464 <p> 3465 This example is a bit contrived, because the compile-time evaluation component is unnecessary; 3466 this code would work fine if it was all done at run-time. But it does end up generating 3467 different code. In this example, the function <code>performFn</code> is generated three different times, 3468 for the different values of <code>prefix_char</code> provided: 3469 </p> 3470 {#code_begin|syntax#} 3471 // From the line: 3472 // assert(performFn('t', 1) == 6); 3473 fn performFn(start_value: i32) i32 { 3474 var result: i32 = start_value; 3475 result = two(result); 3476 result = three(result); 3477 return result; 3478 } 3479 {#code_end#} 3480 {#code_begin|syntax#} 3481 // From the line: 3482 // assert(performFn('o', 0) == 1); 3483 fn performFn(start_value: i32) i32 { 3484 var result: i32 = start_value; 3485 result = one(result); 3486 return result; 3487 } 3488 {#code_end#} 3489 {#code_begin|syntax#} 3490 // From the line: 3491 // assert(performFn('w', 99) == 99); 3492 fn performFn(start_value: i32) i32 { 3493 var result: i32 = start_value; 3494 return result; 3495 } 3496 {#code_end#} 3497 <p> 3498 Note that this happens even in a debug build; in a release build these generated functions still 3499 pass through rigorous LLVM optimizations. The important thing to note, however, is not that this 3500 is a way to write more optimized code, but that it is a way to make sure that what <em>should</em> happen 3501 at compile-time, <em>does</em> happen at compile-time. This catches more errors and as demonstrated 3502 later in this article, allows expressiveness that in other languages requires using macros, 3503 generated code, or a preprocessor to accomplish. 3504 </p> 3505 {#header_close#} 3506 {#header_open|Compile-Time Expressions#} 3507 <p> 3508 In Zig, it matters whether a given expression is known at compile-time or run-time. A programmer can 3509 use a <code>comptime</code> expression to guarantee that the expression will be evaluated at compile-time. 3510 If this cannot be accomplished, the compiler will emit an error. For example: 3511 </p> 3512 {#code_begin|test_err|unable to evaluate constant expression#} 3513 extern fn exit() noreturn; 3514 3515 test "foo" { 3516 comptime { 3517 exit(); 3518 } 3519 } 3520 {#code_end#} 3521 <p> 3522 It doesn't make sense that a program could call <code>exit()</code> (or any other external function) 3523 at compile-time, so this is a compile error. However, a <code>comptime</code> expression does much 3524 more than sometimes cause a compile error. 3525 </p> 3526 <p> 3527 Within a <code>comptime</code> expression: 3528 </p> 3529 <ul> 3530 <li>All variables are <code>comptime</code> variables.</li> 3531 <li>All <code>if</code>, <code>while</code>, <code>for</code>, and <code>switch</code> 3532 expressions are evaluated at compile-time, or emit a compile error if this is not possible.</li> 3533 <li>All function calls cause the compiler to interpret the function at compile-time, emitting a 3534 compile error if the function tries to do something that has global run-time side effects.</li> 3535 </ul> 3536 <p> 3537 This means that a programmer can create a function which is called both at compile-time and run-time, with 3538 no modification to the function required. 3539 </p> 3540 <p> 3541 Let's look at an example: 3542 </p> 3543 {#code_begin|test#} 3544 const assert = @import("std").debug.assert; 3545 3546 fn fibonacci(index: u32) u32 { 3547 if (index < 2) return index; 3548 return fibonacci(index - 1) + fibonacci(index - 2); 3549 } 3550 3551 test "fibonacci" { 3552 // test fibonacci at run-time 3553 assert(fibonacci(7) == 13); 3554 3555 // test fibonacci at compile-time 3556 comptime { 3557 assert(fibonacci(7) == 13); 3558 } 3559 } 3560 {#code_end#} 3561 <p> 3562 Imagine if we had forgotten the base case of the recursive function and tried to run the tests: 3563 </p> 3564 {#code_begin|test_err|operation caused overflow#} 3565 const assert = @import("std").debug.assert; 3566 3567 fn fibonacci(index: u32) u32 { 3568 //if (index < 2) return index; 3569 return fibonacci(index - 1) + fibonacci(index - 2); 3570 } 3571 3572 test "fibonacci" { 3573 comptime { 3574 assert(fibonacci(7) == 13); 3575 } 3576 } 3577 {#code_end#} 3578 <p> 3579 The compiler produces an error which is a stack trace from trying to evaluate the 3580 function at compile-time. 3581 </p> 3582 <p> 3583 Luckily, we used an unsigned integer, and so when we tried to subtract 1 from 0, it triggered 3584 undefined behavior, which is always a compile error if the compiler knows it happened. 3585 But what would have happened if we used a signed integer? 3586 </p> 3587 {#code_begin|test_err|evaluation exceeded 1000 backwards branches#} 3588 const assert = @import("std").debug.assert; 3589 3590 fn fibonacci(index: i32) i32 { 3591 //if (index < 2) return index; 3592 return fibonacci(index - 1) + fibonacci(index - 2); 3593 } 3594 3595 test "fibonacci" { 3596 comptime { 3597 assert(fibonacci(7) == 13); 3598 } 3599 } 3600 {#code_end#} 3601 <p> 3602 The compiler noticed that evaluating this function at compile-time took a long time, 3603 and thus emitted a compile error and gave up. If the programmer wants to increase 3604 the budget for compile-time computation, they can use a built-in function called 3605 {#link|@setEvalBranchQuota#} to change the default number 1000 to something else. 3606 </p> 3607 <p> 3608 What if we fix the base case, but put the wrong value in the <code>assert</code> line? 3609 </p> 3610 {#code_begin|test_err|encountered @panic at compile-time#} 3611 const assert = @import("std").debug.assert; 3612 3613 fn fibonacci(index: i32) i32 { 3614 if (index < 2) return index; 3615 return fibonacci(index - 1) + fibonacci(index - 2); 3616 } 3617 3618 test "fibonacci" { 3619 comptime { 3620 assert(fibonacci(7) == 99999); 3621 } 3622 } 3623 {#code_end#} 3624 <p> 3625 What happened is Zig started interpreting the <code>assert</code> function with the 3626 parameter <code>ok</code> set to <code>false</code>. When the interpreter hit 3627 <code>unreachable</code> it emitted a compile error, because reaching unreachable 3628 code is undefined behavior, and undefined behavior causes a compile error if it is detected 3629 at compile-time. 3630 </p> 3631 3632 <p> 3633 In the global scope (outside of any function), all expressions are implicitly 3634 <code>comptime</code> expressions. This means that we can use functions to 3635 initialize complex static data. For example: 3636 </p> 3637 {#code_begin|test#} 3638 const first_25_primes = firstNPrimes(25); 3639 const sum_of_first_25_primes = sum(first_25_primes); 3640 3641 fn firstNPrimes(comptime n: usize) [n]i32 { 3642 var prime_list: [n]i32 = undefined; 3643 var next_index: usize = 0; 3644 var test_number: i32 = 2; 3645 while (next_index < prime_list.len) : (test_number += 1) { 3646 var test_prime_index: usize = 0; 3647 var is_prime = true; 3648 while (test_prime_index < next_index) : (test_prime_index += 1) { 3649 if (test_number % prime_list[test_prime_index] == 0) { 3650 is_prime = false; 3651 break; 3652 } 3653 } 3654 if (is_prime) { 3655 prime_list[next_index] = test_number; 3656 next_index += 1; 3657 } 3658 } 3659 return prime_list; 3660 } 3661 3662 fn sum(numbers: []const i32) i32 { 3663 var result: i32 = 0; 3664 for (numbers) |x| { 3665 result += x; 3666 } 3667 return result; 3668 } 3669 3670 test "variable values" { 3671 @import("std").debug.assert(sum_of_first_25_primes == 1060); 3672 } 3673 {#code_end#} 3674 <p> 3675 When we compile this program, Zig generates the constants 3676 with the answer pre-computed. Here are the lines from the generated LLVM IR: 3677 </p> 3678 <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] 3679 @1 = internal unnamed_addr constant i32 1060</code></pre> 3680 <p> 3681 Note that we did not have to do anything special with the syntax of these functions. For example, 3682 we could call the <code>sum</code> function as is with a slice of numbers whose length and values were 3683 only known at run-time. 3684 </p> 3685 {#header_close#} 3686 {#header_close#} 3687 {#header_open|Generic Data Structures#} 3688 <p> 3689 Zig uses these capabilities to implement generic data structures without introducing any 3690 special-case syntax. If you followed along so far, you may already know how to create a 3691 generic data structure. 3692 </p> 3693 <p> 3694 Here is an example of a generic <code>List</code> data structure, that we will instantiate with 3695 the type <code>i32</code>. In Zig we refer to the type as <code>List(i32)</code>. 3696 </p> 3697 {#code_begin|syntax#} 3698 fn List(comptime T: type) type { 3699 return struct { 3700 items: []T, 3701 len: usize, 3702 }; 3703 } 3704 {#code_end#} 3705 <p> 3706 That's it. It's a function that returns an anonymous <code>struct</code>. For the purposes of error messages 3707 and debugging, Zig infers the name <code>"List(i32)"</code> from the function name and parameters invoked when creating 3708 the anonymous struct. 3709 </p> 3710 <p> 3711 To keep the language small and uniform, all aggregate types in Zig are anonymous. To give a type 3712 a name, we assign it to a constant: 3713 </p> 3714 {#code_begin|syntax#} 3715 const Node = struct { 3716 next: *Node, 3717 name: []u8, 3718 }; 3719 {#code_end#} 3720 <p> 3721 This works because all top level declarations are order-independent, and as long as there isn't 3722 an actual infinite regression, values can refer to themselves, directly or indirectly. In this case, 3723 <code>Node</code> refers to itself as a pointer, which is not actually an infinite regression, so 3724 it works fine. 3725 </p> 3726 {#header_close#} 3727 {#header_open|Case Study: printf in Zig#} 3728 <p> 3729 Putting all of this together, let's see how <code>printf</code> works in Zig. 3730 </p> 3731 {#code_begin|exe|printf#} 3732 const warn = @import("std").debug.warn; 3733 3734 const a_number: i32 = 1234; 3735 const a_string = "foobar"; 3736 3737 pub fn main() void { 3738 warn("here is a string: '{}' here is a number: {}\n", a_string, a_number); 3739 } 3740 {#code_end#} 3741 3742 <p> 3743 Let's crack open the implementation of this and see how it works: 3744 </p> 3745 3746 {#code_begin|syntax#} 3747 /// Calls print and then flushes the buffer. 3748 pub fn printf(self: *OutStream, comptime format: []const u8, args: ...) error!void { 3749 const State = enum { 3750 Start, 3751 OpenBrace, 3752 CloseBrace, 3753 }; 3754 3755 comptime var start_index: usize = 0; 3756 comptime var state = State.Start; 3757 comptime var next_arg: usize = 0; 3758 3759 inline for (format) |c, i| { 3760 switch (state) { 3761 State.Start => switch (c) { 3762 '{' => { 3763 if (start_index < i) try self.write(format[start_index..i]); 3764 state = State.OpenBrace; 3765 }, 3766 '}' => { 3767 if (start_index < i) try self.write(format[start_index..i]); 3768 state = State.CloseBrace; 3769 }, 3770 else => {}, 3771 }, 3772 State.OpenBrace => switch (c) { 3773 '{' => { 3774 state = State.Start; 3775 start_index = i; 3776 }, 3777 '}' => { 3778 try self.printValue(args[next_arg]); 3779 next_arg += 1; 3780 state = State.Start; 3781 start_index = i + 1; 3782 }, 3783 else => @compileError("Unknown format character: " ++ c), 3784 }, 3785 State.CloseBrace => switch (c) { 3786 '}' => { 3787 state = State.Start; 3788 start_index = i; 3789 }, 3790 else => @compileError("Single '}' encountered in format string"), 3791 }, 3792 } 3793 } 3794 comptime { 3795 if (args.len != next_arg) { 3796 @compileError("Unused arguments"); 3797 } 3798 if (state != State.Start) { 3799 @compileError("Incomplete format string: " ++ format); 3800 } 3801 } 3802 if (start_index < format.len) { 3803 try self.write(format[start_index..format.len]); 3804 } 3805 try self.flush(); 3806 } 3807 {#code_end#} 3808 <p> 3809 This is a proof of concept implementation; the actual function in the standard library has more 3810 formatting capabilities. 3811 </p> 3812 <p> 3813 Note that this is not hard-coded into the Zig compiler; this is userland code in the standard library. 3814 </p> 3815 <p> 3816 When this function is analyzed from our example code above, Zig partially evaluates the function 3817 and emits a function that actually looks like this: 3818 </p> 3819 {#code_begin|syntax#} 3820 pub fn printf(self: *OutStream, arg0: i32, arg1: []const u8) !void { 3821 try self.write("here is a string: '"); 3822 try self.printValue(arg0); 3823 try self.write("' here is a number: "); 3824 try self.printValue(arg1); 3825 try self.write("\n"); 3826 try self.flush(); 3827 } 3828 {#code_end#} 3829 <p> 3830 <code>printValue</code> is a function that takes a parameter of any type, and does different things depending 3831 on the type: 3832 </p> 3833 {#code_begin|syntax#} 3834 pub fn printValue(self: *OutStream, value: var) !void { 3835 const T = @typeOf(value); 3836 if (@isInteger(T)) { 3837 return self.printInt(T, value); 3838 } else if (@isFloat(T)) { 3839 return self.printFloat(T, value); 3840 } else if (@canImplicitCast([]const u8, value)) { 3841 const casted_value = ([]const u8)(value); 3842 return self.write(casted_value); 3843 } else { 3844 @compileError("Unable to print type '" ++ @typeName(T) ++ "'"); 3845 } 3846 } 3847 {#code_end#} 3848 <p> 3849 And now, what happens if we give too many arguments to <code>printf</code>? 3850 </p> 3851 {#code_begin|test_err|Unused arguments#} 3852 const warn = @import("std").debug.warn; 3853 3854 const a_number: i32 = 1234; 3855 const a_string = "foobar"; 3856 3857 test "printf too many arguments" { 3858 warn("here is a string: '{}' here is a number: {}\n", 3859 a_string, a_number, a_number); 3860 } 3861 {#code_end#} 3862 <p> 3863 Zig gives programmers the tools needed to protect themselves against their own mistakes. 3864 </p> 3865 <p> 3866 Zig doesn't care whether the format argument is a string literal, 3867 only that it is a compile-time known value that is implicitly castable to a <code>[]const u8</code>: 3868 </p> 3869 {#code_begin|exe|printf#} 3870 const warn = @import("std").debug.warn; 3871 3872 const a_number: i32 = 1234; 3873 const a_string = "foobar"; 3874 const fmt = "here is a string: '{}' here is a number: {}\n"; 3875 3876 pub fn main() void { 3877 warn(fmt, a_string, a_number); 3878 } 3879 {#code_end#} 3880 <p> 3881 This works fine. 3882 </p> 3883 <p> 3884 Zig does not special case string formatting in the compiler and instead exposes enough power to accomplish this 3885 task in userland. It does so without introducing another language on top of Zig, such as 3886 a macro language or a preprocessor language. It's Zig all the way down. 3887 </p> 3888 <p>TODO: suggestion to not use inline unless necessary</p> 3889 {#header_close#} 3890 {#header_close#} 3891 {#header_open|inline#} 3892 <p>TODO: inline while</p> 3893 <p>TODO: inline for</p> 3894 <p>TODO: suggestion to not use inline unless necessary</p> 3895 {#header_close#} 3896 {#header_open|Assembly#} 3897 <p>TODO: example of inline assembly</p> 3898 <p>TODO: example of module level assembly</p> 3899 <p>TODO: example of using inline assembly return value</p> 3900 <p>TODO: example of using inline assembly assigning values to variables</p> 3901 {#header_close#} 3902 {#header_open|Atomics#} 3903 <p>TODO: @fence()</p> 3904 <p>TODO: @atomic rmw</p> 3905 <p>TODO: builtin atomic memory ordering enum</p> 3906 {#header_close#} 3907 {#header_open|Builtin Functions#} 3908 <p> 3909 Builtin functions are provided by the compiler and are prefixed with <code>@</code>. 3910 The <code>comptime</code> keyword on a parameter means that the parameter must be known 3911 at compile time. 3912 </p> 3913 {#header_open|@addWithOverflow#} 3914 <pre><code class="zig">@addWithOverflow(comptime T: type, a: T, b: T, result: *T) bool</code></pre> 3915 <p> 3916 Performs <code>result.* = a + b</code>. If overflow or underflow occurs, 3917 stores the overflowed bits in <code>result</code> and returns <code>true</code>. 3918 If no overflow or underflow occurs, returns <code>false</code>. 3919 </p> 3920 {#header_close#} 3921 {#header_open|@ArgType#} 3922 <pre><code class="zig">@ArgType(comptime T: type, comptime n: usize) type</code></pre> 3923 <p> 3924 This builtin function takes a function type and returns the type of the parameter at index <code>n</code>. 3925 </p> 3926 <p> 3927 <code>T</code> must be a function type. 3928 </p> 3929 <p> 3930 Note: This function is deprecated. Use {#link|@typeInfo#} instead. 3931 </p> 3932 {#header_close#} 3933 {#header_open|@atomicLoad#} 3934 <pre><code class="zig">@atomicLoad(comptime T: type, ptr: *const T, comptime ordering: builtin.AtomicOrder) T</code></pre> 3935 <p> 3936 This builtin function atomically dereferences a pointer and returns the value. 3937 </p> 3938 <p> 3939 <code>T</code> must be a pointer type, a <code>bool</code>, 3940 or an integer whose bit count meets these requirements: 3941 </p> 3942 <ul> 3943 <li>At least 8</li> 3944 <li>At most the same as usize</li> 3945 <li>Power of 2</li> 3946 </ul> 3947 <p> 3948 TODO right now bool is not accepted. Also I think we could make non powers of 2 work fine, maybe 3949 we can remove this restriction 3950 </p> 3951 {#header_close#} 3952 {#header_open|@atomicRmw#} 3953 <pre><code class="zig">@atomicRmw(comptime T: type, ptr: *T, comptime op: builtin.AtomicRmwOp, operand: T, comptime ordering: builtin.AtomicOrder) T</code></pre> 3954 <p> 3955 This builtin function atomically modifies memory and then returns the previous value. 3956 </p> 3957 <p> 3958 <code>T</code> must be a pointer type, a <code>bool</code>, 3959 or an integer whose bit count meets these requirements: 3960 </p> 3961 <ul> 3962 <li>At least 8</li> 3963 <li>At most the same as usize</li> 3964 <li>Power of 2</li> 3965 </ul> 3966 <p> 3967 TODO right now bool is not accepted. Also I think we could make non powers of 2 work fine, maybe 3968 we can remove this restriction 3969 </p> 3970 {#header_close#} 3971 {#header_open|@bitCast#} 3972 <pre><code class="zig">@bitCast(comptime DestType: type, value: var) DestType</code></pre> 3973 <p> 3974 Converts a value of one type to another type. 3975 </p> 3976 <p> 3977 Asserts that <code>@sizeOf(@typeOf(value)) == @sizeOf(DestType)</code>. 3978 </p> 3979 <p> 3980 Asserts that <code>@typeId(DestType) != @import("builtin").TypeId.Pointer</code>. Use <code>@ptrCast</code> or <code>@intToPtr</code> if you need this. 3981 </p> 3982 <p> 3983 Can be used for these things for example: 3984 </p> 3985 <ul> 3986 <li>Convert <code>f32</code> to <code>u32</code> bits</li> 3987 <li>Convert <code>i32</code> to <code>u32</code> preserving twos complement</li> 3988 </ul> 3989 <p> 3990 Works at compile-time if <code>value</code> 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. 3991 </p> 3992 {#header_close#} 3993 {#header_open|@breakpoint#} 3994 <pre><code class="zig">@breakpoint()</code></pre> 3995 <p> 3996 This function inserts a platform-specific debug trap instruction which causes 3997 debuggers to break there. 3998 </p> 3999 <p> 4000 This function is only valid within function scope. 4001 </p> 4002 4003 {#header_close#} 4004 {#header_open|@alignCast#} 4005 <pre><code class="zig">@alignCast(comptime alignment: u29, ptr: var) var</code></pre> 4006 <p> 4007 <code>ptr</code> can be <code>*T</code>, <code>fn()</code>, <code>?*T</code>, 4008 <code>?fn()</code>, or <code>[]T</code>. It returns the same type as <code>ptr</code> 4009 except with the alignment adjusted to the new value. 4010 </p> 4011 <p>A {#link|pointer alignment safety check|Incorrect Pointer Alignment#} is added 4012 to the generated code to make sure the pointer is aligned as promised.</p> 4013 4014 {#header_close#} 4015 {#header_open|@alignOf#} 4016 <pre><code class="zig">@alignOf(comptime T: type) (number literal)</code></pre> 4017 <p> 4018 This function returns the number of bytes that this type should be aligned to 4019 for the current target to match the C ABI. When the child type of a pointer has 4020 this alignment, the alignment can be omitted from the type. 4021 </p> 4022 <pre><code class="zig">const assert = @import("std").debug.assert; 4023 comptime { 4024 assert(*u32 == *align(@alignOf(u32)) u32); 4025 }</code></pre> 4026 <p> 4027 The result is a target-specific compile time constant. It is guaranteed to be 4028 less than or equal to {#link|@sizeOf(T)|@sizeOf#}. 4029 </p> 4030 {#see_also|Alignment#} 4031 {#header_close#} 4032 {#header_open|@cDefine#} 4033 <pre><code class="zig">@cDefine(comptime name: []u8, value)</code></pre> 4034 <p> 4035 This function can only occur inside <code>@cImport</code>. 4036 </p> 4037 <p> 4038 This appends <code>#define $name $value</code> to the <code>@cImport</code> 4039 temporary buffer. 4040 </p> 4041 <p> 4042 To define without a value, like this: 4043 </p> 4044 <pre><code class="c">#define _GNU_SOURCE</code></pre> 4045 <p> 4046 Use the void value, like this: 4047 </p> 4048 <pre><code class="zig">@cDefine("_GNU_SOURCE", {})</code></pre> 4049 {#see_also|Import from C Header File|@cInclude|@cImport|@cUndef|void#} 4050 {#header_close#} 4051 {#header_open|@cImport#} 4052 <pre><code class="zig">@cImport(expression) (namespace)</code></pre> 4053 <p> 4054 This function parses C code and imports the functions, types, variables, and 4055 compatible macro definitions into the result namespace. 4056 </p> 4057 <p> 4058 <code>expression</code> is interpreted at compile time. The builtin functions 4059 <code>@cInclude</code>, <code>@cDefine</code>, and <code>@cUndef</code> work 4060 within this expression, appending to a temporary buffer which is then parsed as C code. 4061 </p> 4062 <p> 4063 Usually you should only have one <code>@cImport</code> in your entire application, because it saves the compiler 4064 from invoking clang multiple times, and prevents inline functions from being duplicated. 4065 </p> 4066 <p> 4067 Reasons for having multiple <code>@cImport</code> expressions would be: 4068 </p> 4069 <ul> 4070 <li>To avoid a symbol collision, for example if foo.h and bar.h both <code>#define CONNECTION_COUNT</code></li> 4071 <li>To analyze the C code with different preprocessor defines</li> 4072 </ul> 4073 {#see_also|Import from C Header File|@cInclude|@cDefine|@cUndef#} 4074 {#header_close#} 4075 {#header_open|@cInclude#} 4076 <pre><code class="zig">@cInclude(comptime path: []u8)</code></pre> 4077 <p> 4078 This function can only occur inside <code>@cImport</code>. 4079 </p> 4080 <p> 4081 This appends <code>#include <$path>\n</code> to the <code>c_import</code> 4082 temporary buffer. 4083 </p> 4084 {#see_also|Import from C Header File|@cImport|@cDefine|@cUndef#} 4085 {#header_close#} 4086 {#header_open|@cUndef#} 4087 <pre><code class="zig">@cUndef(comptime name: []u8)</code></pre> 4088 <p> 4089 This function can only occur inside <code>@cImport</code>. 4090 </p> 4091 <p> 4092 This appends <code>#undef $name</code> to the <code>@cImport</code> 4093 temporary buffer. 4094 </p> 4095 {#see_also|Import from C Header File|@cImport|@cDefine|@cInclude#} 4096 {#header_close#} 4097 {#header_open|@canImplicitCast#} 4098 <pre><code class="zig">@canImplicitCast(comptime T: type, value) bool</code></pre> 4099 <p> 4100 Returns whether a value can be implicitly casted to a given type. 4101 </p> 4102 {#header_close#} 4103 {#header_open|@clz#} 4104 <pre><code class="zig">@clz(x: T) U</code></pre> 4105 <p> 4106 This function counts the number of leading zeroes in <code>x</code> which is an integer 4107 type <code>T</code>. 4108 </p> 4109 <p> 4110 The return type <code>U</code> is an unsigned integer with the minimum number 4111 of bits that can represent the value <code>T.bit_count</code>. 4112 </p> 4113 <p> 4114 If <code>x</code> is zero, <code>@clz</code> returns <code>T.bit_count</code>. 4115 </p> 4116 4117 {#header_close#} 4118 {#header_open|@cmpxchgStrong#} 4119 <pre><code class="zig">@cmpxchgStrong(comptime T: type, ptr: *T, expected_value: T, new_value: T, success_order: AtomicOrder, fail_order: AtomicOrder) ?T</code></pre> 4120 <p> 4121 This function performs a strong atomic compare exchange operation. It's the equivalent of this code, 4122 except atomic: 4123 </p> 4124 {#code_begin|syntax#} 4125 fn cmpxchgStrongButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_value: T) ?T { 4126 const old_value = ptr.*; 4127 if (old_value == expected_value) { 4128 ptr.* = new_value; 4129 return null; 4130 } else { 4131 return old_value; 4132 } 4133 } 4134 {#code_end#} 4135 <p> 4136 If you are using cmpxchg in a loop, {#link|@cmpxchgWeak#} is the better choice, because it can be implemented 4137 more efficiently in machine instructions. 4138 </p> 4139 <p> 4140 <code>AtomicOrder</code> can be found with <code>@import("builtin").AtomicOrder</code>. 4141 </p> 4142 <p><code>@typeOf(ptr).alignment</code> must be <code>>= @sizeOf(T).</code></p> 4143 {#see_also|Compile Variables|cmpxchgWeak#} 4144 {#header_close#} 4145 {#header_open|@cmpxchgWeak#} 4146 <pre><code class="zig">@cmpxchgWeak(comptime T: type, ptr: *T, expected_value: T, new_value: T, success_order: AtomicOrder, fail_order: AtomicOrder) ?T</code></pre> 4147 <p> 4148 This function performs a weak atomic compare exchange operation. It's the equivalent of this code, 4149 except atomic: 4150 </p> 4151 {#code_begin|syntax#} 4152 fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_value: T) ?T { 4153 const old_value = ptr.*; 4154 if (old_value == expected_value and usuallyTrueButSometimesFalse()) { 4155 ptr.* = new_value; 4156 return null; 4157 } else { 4158 return old_value; 4159 } 4160 } 4161 {#code_end#} 4162 <p> 4163 If you are using cmpxchg in a loop, the sporadic failure will be no problem, and <code>cmpxchgWeak</code> 4164 is the better choice, because it can be implemented more efficiently in machine instructions. 4165 However if you need a stronger guarantee, use {#link|@cmpxchgStrong#}. 4166 </p> 4167 <p> 4168 <code>AtomicOrder</code> can be found with <code>@import("builtin").AtomicOrder</code>. 4169 </p> 4170 <p><code>@typeOf(ptr).alignment</code> must be <code>>= @sizeOf(T).</code></p> 4171 {#see_also|Compile Variables|cmpxchgStrong#} 4172 {#header_close#} 4173 {#header_open|@compileError#} 4174 <pre><code class="zig">@compileError(comptime msg: []u8)</code></pre> 4175 <p> 4176 This function, when semantically analyzed, causes a compile error with the 4177 message <code>msg</code>. 4178 </p> 4179 <p> 4180 There are several ways that code avoids being semantically checked, such as 4181 using <code>if</code> or <code>switch</code> with compile time constants, 4182 and <code>comptime</code> functions. 4183 </p> 4184 {#header_close#} 4185 {#header_open|@compileLog#} 4186 <pre><code class="zig">@compileLog(args: ...)</code></pre> 4187 <p> 4188 This function prints the arguments passed to it at compile-time. 4189 </p> 4190 <p> 4191 To prevent accidentally leaving compile log statements in a codebase, 4192 a compilation error is added to the build, pointing to the compile 4193 log statement. This error prevents code from being generated, but 4194 does not otherwise interfere with analysis. 4195 </p> 4196 <p> 4197 This function can be used to do "printf debugging" on 4198 compile-time executing code. 4199 </p> 4200 {#code_begin|test_err|found compile log statement#} 4201 const warn = @import("std").debug.warn; 4202 4203 const num1 = blk: { 4204 var val1: i32 = 99; 4205 @compileLog("comptime val1 = ", val1); 4206 val1 = val1 + 1; 4207 break :blk val1; 4208 }; 4209 4210 test "main" { 4211 @compileLog("comptime in main"); 4212 4213 warn("Runtime in main, num1 = {}.\n", num1); 4214 } 4215 {#code_end#} 4216 </p> 4217 <p> 4218 will ouput: 4219 </p> 4220 <p> 4221 If all <code>@compileLog</code> calls are removed or 4222 not encountered by analysis, the 4223 program compiles successfully and the generated executable prints: 4224 </p> 4225 {#code_begin|test#} 4226 const warn = @import("std").debug.warn; 4227 4228 const num1 = blk: { 4229 var val1: i32 = 99; 4230 val1 = val1 + 1; 4231 break :blk val1; 4232 }; 4233 4234 test "main" { 4235 warn("Runtime in main, num1 = {}.\n", num1); 4236 } 4237 {#code_end#} 4238 {#header_close#} 4239 {#header_open|@ctz#} 4240 <pre><code class="zig">@ctz(x: T) U</code></pre> 4241 <p> 4242 This function counts the number of trailing zeroes in <code>x</code> which is an integer 4243 type <code>T</code>. 4244 </p> 4245 <p> 4246 The return type <code>U</code> is an unsigned integer with the minimum number 4247 of bits that can represent the value <code>T.bit_count</code>. 4248 </p> 4249 <p> 4250 If <code>x</code> is zero, <code>@ctz</code> returns <code>T.bit_count</code>. 4251 </p> 4252 {#header_close#} 4253 {#header_open|@divExact#} 4254 <pre><code class="zig">@divExact(numerator: T, denominator: T) T</code></pre> 4255 <p> 4256 Exact division. Caller guarantees <code>denominator != 0</code> and 4257 <code>@divTrunc(numerator, denominator) * denominator == numerator</code>. 4258 </p> 4259 <ul> 4260 <li><code>@divExact(6, 3) == 2</code></li> 4261 <li><code>@divExact(a, b) * b == a</code></li> 4262 </ul> 4263 <p>For a function that returns a possible error code, use <code>@import("std").math.divExact</code>.</p> 4264 {#see_also|@divTrunc|@divFloor#} 4265 {#header_close#} 4266 {#header_open|@divFloor#} 4267 <pre><code class="zig">@divFloor(numerator: T, denominator: T) T</code></pre> 4268 <p> 4269 Floored division. Rounds toward negative infinity. For unsigned integers it is 4270 the same as <code>numerator / denominator</code>. Caller guarantees <code>denominator != 0</code> and 4271 <code>!(@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)</code>. 4272 </p> 4273 <ul> 4274 <li><code>@divFloor(-5, 3) == -2</code></li> 4275 <li><code>@divFloor(a, b) + @mod(a, b) == a</code></li> 4276 </ul> 4277 <p>For a function that returns a possible error code, use <code>@import("std").math.divFloor</code>.</p> 4278 {#see_also|@divTrunc|@divExact#} 4279 {#header_close#} 4280 {#header_open|@divTrunc#} 4281 <pre><code class="zig">@divTrunc(numerator: T, denominator: T) T</code></pre> 4282 <p> 4283 Truncated division. Rounds toward zero. For unsigned integers it is 4284 the same as <code>numerator / denominator</code>. Caller guarantees <code>denominator != 0</code> and 4285 <code>!(@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)</code>. 4286 </p> 4287 <ul> 4288 <li><code>@divTrunc(-5, 3) == -1</code></li> 4289 <li><code>@divTrunc(a, b) + @rem(a, b) == a</code></li> 4290 </ul> 4291 <p>For a function that returns a possible error code, use <code>@import("std").math.divTrunc</code>.</p> 4292 {#see_also|@divFloor|@divExact#} 4293 {#header_close#} 4294 {#header_open|@embedFile#} 4295 <pre><code class="zig">@embedFile(comptime path: []const u8) [X]u8</code></pre> 4296 <p> 4297 This function returns a compile time constant fixed-size array with length 4298 equal to the byte count of the file given by <code>path</code>. The contents of the array 4299 are the contents of the file. 4300 </p> 4301 <p> 4302 <code>path</code> is absolute or relative to the current file, just like <code>@import</code>. 4303 </p> 4304 {#see_also|@import#} 4305 {#header_close#} 4306 {#header_open|@export#} 4307 <pre><code class="zig">@export(comptime name: []const u8, target: var, linkage: builtin.GlobalLinkage) []const u8</code></pre> 4308 <p> 4309 Creates a symbol in the output object file. 4310 </p> 4311 {#header_close#} 4312 {#header_open|@tagName#} 4313 <pre><code class="zig">@tagName(value: var) []const u8</code></pre> 4314 <p> 4315 Converts an enum value or union value to a slice of bytes representing the name. 4316 </p> 4317 {#header_close#} 4318 {#header_open|@TagType#} 4319 <pre><code class="zig">@TagType(T: type) type</code></pre> 4320 <p> 4321 For an enum, returns the integer type that is used to store the enumeration value. 4322 </p> 4323 <p> 4324 For a union, returns the enum type that is used to store the tag value. 4325 </p> 4326 {#header_close#} 4327 {#header_open|@errorName#} 4328 <pre><code class="zig">@errorName(err: error) []u8</code></pre> 4329 <p> 4330 This function returns the string representation of an error. If an error 4331 declaration is: 4332 </p> 4333 <pre><code class="zig">error OutOfMem</code></pre> 4334 <p> 4335 Then the string representation is <code>"OutOfMem"</code>. 4336 </p> 4337 <p> 4338 If there are no calls to <code>@errorName</code> in an entire application, 4339 or all calls have a compile-time known value for <code>err</code>, then no 4340 error name table will be generated. 4341 </p> 4342 {#header_close#} 4343 {#header_open|@errorReturnTrace#} 4344 <pre><code class="zig">@errorReturnTrace() ?*builtin.StackTrace</code></pre> 4345 <p> 4346 If the binary is built with error return tracing, and this function is invoked in a 4347 function that calls a function with an error or error union return type, returns a 4348 stack trace object. Otherwise returns `null`. 4349 </p> 4350 {#header_close#} 4351 {#header_open|@fence#} 4352 <pre><code class="zig">@fence(order: AtomicOrder)</code></pre> 4353 <p> 4354 The <code>fence</code> function is used to introduce happens-before edges between operations. 4355 </p> 4356 <p> 4357 <code>AtomicOrder</code> can be found with <code>@import("builtin").AtomicOrder</code>. 4358 </p> 4359 {#see_also|Compile Variables#} 4360 {#header_close#} 4361 {#header_open|@fieldParentPtr#} 4362 <pre><code class="zig">@fieldParentPtr(comptime ParentType: type, comptime field_name: []const u8, 4363 field_ptr: *T) *ParentType</code></pre> 4364 <p> 4365 Given a pointer to a field, returns the base pointer of a struct. 4366 </p> 4367 {#header_close#} 4368 {#header_open|@frameAddress#} 4369 <pre><code class="zig">@frameAddress()</code></pre> 4370 <p> 4371 This function returns the base pointer of the current stack frame. 4372 </p> 4373 <p> 4374 The implications of this are target specific and not consistent across all 4375 platforms. The frame address may not be available in release mode due to 4376 aggressive optimizations. 4377 </p> 4378 <p> 4379 This function is only valid within function scope. 4380 </p> 4381 {#header_close#} 4382 {#header_open|@import#} 4383 <pre><code class="zig">@import(comptime path: []u8) (namespace)</code></pre> 4384 <p> 4385 This function finds a zig file corresponding to <code>path</code> and imports all the 4386 public top level declarations into the resulting namespace. 4387 </p> 4388 <p> 4389 <code>path</code> can be a relative or absolute path, or it can be the name of a package. 4390 If it is a relative path, it is relative to the file that contains the <code>@import</code> 4391 function call. 4392 </p> 4393 <p> 4394 The following packages are always available: 4395 </p> 4396 <ul> 4397 <li><code>@import("std")</code> - Zig Standard Library</li> 4398 <li><code>@import("builtin")</code> - Compiler-provided types and variables</li> 4399 </ul> 4400 {#see_also|Compile Variables|@embedFile#} 4401 {#header_close#} 4402 {#header_open|@inlineCall#} 4403 <pre><code class="zig">@inlineCall(function: X, args: ...) Y</code></pre> 4404 <p> 4405 This calls a function, in the same way that invoking an expression with parentheses does: 4406 </p> 4407 {#code_begin|test#} 4408 const assert = @import("std").debug.assert; 4409 4410 test "inline function call" { 4411 assert(@inlineCall(add, 3, 9) == 12); 4412 } 4413 4414 fn add(a: i32, b: i32) i32 { return a + b; } 4415 {#code_end#} 4416 <p> 4417 Unlike a normal function call, however, <code>@inlineCall</code> guarantees that the call 4418 will be inlined. If the call cannot be inlined, a compile error is emitted. 4419 </p> 4420 {#see_also|@noInlineCall#} 4421 {#header_close#} 4422 {#header_open|@intToPtr#} 4423 <pre><code class="zig">@intToPtr(comptime DestType: type, int: usize) DestType</code></pre> 4424 <p> 4425 Converts an integer to a pointer. To convert the other way, use {#link|@ptrToInt#}. 4426 </p> 4427 {#header_close#} 4428 {#header_open|@IntType#} 4429 <pre><code class="zig">@IntType(comptime is_signed: bool, comptime bit_count: u8) type</code></pre> 4430 <p> 4431 This function returns an integer type with the given signness and bit count. 4432 </p> 4433 {#header_close#} 4434 {#header_open|@maxValue#} 4435 <pre><code class="zig">@maxValue(comptime T: type) (number literal)</code></pre> 4436 <p> 4437 This function returns the maximum value of the integer type <code>T</code>. 4438 </p> 4439 <p> 4440 The result is a compile time constant. 4441 </p> 4442 {#header_close#} 4443 {#header_open|@memberCount#} 4444 <pre><code class="zig">@memberCount(comptime T: type) (number literal)</code></pre> 4445 <p> 4446 This function returns the number of members in a struct, enum, or union type. 4447 </p> 4448 <p> 4449 The result is a compile time constant. 4450 </p> 4451 <p> 4452 It does not include functions, variables, or constants. 4453 </p> 4454 {#header_close#} 4455 {#header_open|@memberName#} 4456 <pre><code class="zig">@memberName(comptime T: type, comptime index: usize) [N]u8</code></pre> 4457 <p>Returns the field name of a struct, union, or enum.</p> 4458 <p> 4459 The result is a compile time constant. 4460 </p> 4461 <p> 4462 It does not include functions, variables, or constants. 4463 </p> 4464 {#header_close#} 4465 {#header_open|@field#} 4466 <pre><code class="zig">@field(lhs: var, comptime field_name: []const u8) (field)</code></pre> 4467 <p>Preforms field access equivalent to <code>lhs.->field_name-<</code>.</p> 4468 {#header_close#} 4469 {#header_open|@memberType#} 4470 <pre><code class="zig">@memberType(comptime T: type, comptime index: usize) type</code></pre> 4471 <p>Returns the field type of a struct or union.</p> 4472 {#header_close#} 4473 {#header_open|@memcpy#} 4474 <pre><code class="zig">@memcpy(noalias dest: *u8, noalias source: *const u8, byte_count: usize)</code></pre> 4475 <p> 4476 This function copies bytes from one region of memory to another. <code>dest</code> and 4477 <code>source</code> are both pointers and must not overlap. 4478 </p> 4479 <p> 4480 This function is a low level intrinsic with no safety mechanisms. Most code 4481 should not use this function, instead using something like this: 4482 </p> 4483 <pre><code class="zig">for (source[0...byte_count]) |b, i| dest[i] = b;</code></pre> 4484 <p> 4485 The optimizer is intelligent enough to turn the above snippet into a memcpy. 4486 </p> 4487 <p>There is also a standard library function for this:</p> 4488 <pre><code class="zig">const mem = @import("std").mem; 4489 mem.copy(u8, dest[0...byte_count], source[0...byte_count]);</code></pre> 4490 {#header_close#} 4491 {#header_open|@memset#} 4492 <pre><code class="zig">@memset(dest: *u8, c: u8, byte_count: usize)</code></pre> 4493 <p> 4494 This function sets a region of memory to <code>c</code>. <code>dest</code> is a pointer. 4495 </p> 4496 <p> 4497 This function is a low level intrinsic with no safety mechanisms. Most 4498 code should not use this function, instead using something like this: 4499 </p> 4500 <pre><code class="zig">for (dest[0...byte_count]) |*b| b.* = c;</code></pre> 4501 <p> 4502 The optimizer is intelligent enough to turn the above snippet into a memset. 4503 </p> 4504 <p>There is also a standard library function for this:</p> 4505 <pre><code>const mem = @import("std").mem; 4506 mem.set(u8, dest, c);</code></pre> 4507 {#header_close#} 4508 {#header_open|@minValue#} 4509 <pre><code class="zig">@minValue(comptime T: type) (number literal)</code></pre> 4510 <p> 4511 This function returns the minimum value of the integer type T. 4512 </p> 4513 <p> 4514 The result is a compile time constant. 4515 </p> 4516 {#header_close#} 4517 {#header_open|@mod#} 4518 <pre><code class="zig">@mod(numerator: T, denominator: T) T</code></pre> 4519 <p> 4520 Modulus division. For unsigned integers this is the same as 4521 <code>numerator % denominator</code>. Caller guarantees <code>denominator > 0</code>. 4522 </p> 4523 <ul> 4524 <li><code>@mod(-5, 3) == 1</code></li> 4525 <li><code>@divFloor(a, b) + @mod(a, b) == a</code></li> 4526 </ul> 4527 <p>For a function that returns an error code, see <code>@import("std").math.mod</code>.</p> 4528 {#see_also|@rem#} 4529 {#header_close#} 4530 {#header_open|@mulWithOverflow#} 4531 <pre><code class="zig">@mulWithOverflow(comptime T: type, a: T, b: T, result: *T) bool</code></pre> 4532 <p> 4533 Performs <code>result.* = a * b</code>. If overflow or underflow occurs, 4534 stores the overflowed bits in <code>result</code> and returns <code>true</code>. 4535 If no overflow or underflow occurs, returns <code>false</code>. 4536 </p> 4537 {#header_close#} 4538 {#header_open|@newStackCall#} 4539 <pre><code class="zig">@newStackCall(new_stack: []u8, function: var, args: ...) var</code></pre> 4540 <p> 4541 This calls a function, in the same way that invoking an expression with parentheses does. However, 4542 instead of using the same stack as the caller, the function uses the stack provided in the <code>new_stack</code> 4543 parameter. 4544 </p> 4545 {#code_begin|test#} 4546 const std = @import("std"); 4547 const assert = std.debug.assert; 4548 4549 var new_stack_bytes: [1024]u8 = undefined; 4550 4551 test "calling a function with a new stack" { 4552 const arg = 1234; 4553 4554 const a = @newStackCall(new_stack_bytes[0..512], targetFunction, arg); 4555 const b = @newStackCall(new_stack_bytes[512..], targetFunction, arg); 4556 _ = targetFunction(arg); 4557 4558 assert(arg == 1234); 4559 assert(a < b); 4560 } 4561 4562 fn targetFunction(x: i32) usize { 4563 assert(x == 1234); 4564 4565 var local_variable: i32 = 42; 4566 const ptr = &local_variable; 4567 ptr.* += 1; 4568 4569 assert(local_variable == 43); 4570 return @ptrToInt(ptr); 4571 } 4572 {#code_end#} 4573 {#header_close#} 4574 {#header_open|@noInlineCall#} 4575 <pre><code class="zig">@noInlineCall(function: var, args: ...) var</code></pre> 4576 <p> 4577 This calls a function, in the same way that invoking an expression with parentheses does: 4578 </p> 4579 {#code_begin|test#} 4580 const assert = @import("std").debug.assert; 4581 4582 test "noinline function call" { 4583 assert(@noInlineCall(add, 3, 9) == 12); 4584 } 4585 4586 fn add(a: i32, b: i32) i32 { 4587 return a + b; 4588 } 4589 {#code_end#} 4590 <p> 4591 Unlike a normal function call, however, <code>@noInlineCall</code> guarantees that the call 4592 will not be inlined. If the call must be inlined, a compile error is emitted. 4593 </p> 4594 {#see_also|@inlineCall#} 4595 {#header_close#} 4596 {#header_open|@offsetOf#} 4597 <pre><code class="zig">@offsetOf(comptime T: type, comptime field_name: [] const u8) (number literal)</code></pre> 4598 <p> 4599 This function returns the byte offset of a field relative to its containing struct. 4600 </p> 4601 {#header_close#} 4602 {#header_open|@OpaqueType#} 4603 <pre><code class="zig">@OpaqueType() type</code></pre> 4604 <p> 4605 Creates a new type with an unknown size and alignment. 4606 </p> 4607 <p> 4608 This is typically used for type safety when interacting with C code that does not expose struct details. 4609 Example: 4610 </p> 4611 {#code_begin|test_err|expected type '*Derp', found '*Wat'#} 4612 const Derp = @OpaqueType(); 4613 const Wat = @OpaqueType(); 4614 4615 extern fn bar(d: *Derp) void; 4616 export fn foo(w: *Wat) void { 4617 bar(w); 4618 } 4619 4620 test "call foo" { 4621 foo(undefined); 4622 } 4623 {#code_end#} 4624 {#header_close#} 4625 {#header_open|@panic#} 4626 <pre><code class="zig">@panic(message: []const u8) noreturn</code></pre> 4627 <p> 4628 Invokes the panic handler function. By default the panic handler function 4629 calls the public <code>panic</code> function exposed in the root source file, or 4630 if there is not one specified, invokes the one provided in <code>std/special/panic.zig</code>. 4631 </p> 4632 <p>Generally it is better to use <code>@import("std").debug.panic</code>. 4633 However, <code>@panic</code> can be useful for 2 scenarios: 4634 </p> 4635 <ul> 4636 <li>From library code, calling the programmer's panic function if they exposed one in the root source file.</li> 4637 <li>When mixing C and Zig code, calling the canonical panic implementation across multiple .o files.</li> 4638 </ul> 4639 {#see_also|Root Source File#} 4640 {#header_close#} 4641 {#header_open|@ptrCast#} 4642 <pre><code class="zig">@ptrCast(comptime DestType: type, value: var) DestType</code></pre> 4643 <p> 4644 Converts a pointer of one type to a pointer of another type. 4645 </p> 4646 {#header_close#} 4647 {#header_open|@ptrToInt#} 4648 <pre><code class="zig">@ptrToInt(value: var) usize</code></pre> 4649 <p> 4650 Converts <code>value</code> to a <code>usize</code> which is the address of the pointer. <code>value</code> can be one of these types: 4651 </p> 4652 <ul> 4653 <li><code>*T</code></li> 4654 <li><code>?*T</code></li> 4655 <li><code>fn()</code></li> 4656 <li><code>?fn()</code></li> 4657 </ul> 4658 <p>To convert the other way, use {#link|@intToPtr#}</p> 4659 4660 {#header_close#} 4661 {#header_open|@rem#} 4662 <pre><code class="zig">@rem(numerator: T, denominator: T) T</code></pre> 4663 <p> 4664 Remainder division. For unsigned integers this is the same as 4665 <code>numerator % denominator</code>. Caller guarantees <code>denominator > 0</code>. 4666 </p> 4667 <ul> 4668 <li><code>@rem(-5, 3) == -2</code></li> 4669 <li><code>@divTrunc(a, b) + @rem(a, b) == a</code></li> 4670 </ul> 4671 <p>For a function that returns an error code, see <code>@import("std").math.rem</code>.</p> 4672 {#see_also|@mod#} 4673 {#header_close#} 4674 {#header_open|@returnAddress#} 4675 <pre><code class="zig">@returnAddress()</code></pre> 4676 <p> 4677 This function returns a pointer to the return address of the current stack 4678 frame. 4679 </p> 4680 <p> 4681 The implications of this are target specific and not consistent across 4682 all platforms. 4683 </p> 4684 <p> 4685 This function is only valid within function scope. 4686 </p> 4687 {#header_close#} 4688 {#header_open|@setAlignStack#} 4689 <pre><code class="zig">@setAlignStack(comptime alignment: u29)</code></pre> 4690 <p> 4691 Ensures that a function will have a stack alignment of at least <code>alignment</code> bytes. 4692 </p> 4693 {#header_close#} 4694 {#header_open|@setCold#} 4695 <pre><code class="zig">@setCold(is_cold: bool)</code></pre> 4696 <p> 4697 Tells the optimizer that a function is rarely called. 4698 </p> 4699 {#header_close#} 4700 {#header_open|@setRuntimeSafety#} 4701 <pre><code class="zig">@setRuntimeSafety(safety_on: bool)</code></pre> 4702 <p> 4703 Sets whether runtime safety checks are on for the scope that contains the function call. 4704 </p> 4705 4706 {#header_close#} 4707 {#header_open|@setEvalBranchQuota#} 4708 <pre><code class="zig">@setEvalBranchQuota(new_quota: usize)</code></pre> 4709 <p> 4710 Changes the maximum number of backwards branches that compile-time code 4711 execution can use before giving up and making a compile error. 4712 </p> 4713 <p> 4714 If the <code>new_quota</code> is smaller than the default quota (<code>1000</code>) or 4715 a previously explicitly set quota, it is ignored. 4716 </p> 4717 <p> 4718 Example: 4719 </p> 4720 {#code_begin|test_err|evaluation exceeded 1000 backwards branches#} 4721 test "foo" { 4722 comptime { 4723 var i = 0; 4724 while (i < 1001) : (i += 1) {} 4725 } 4726 } 4727 {#code_end#} 4728 <p>Now we use <code class="zig">@setEvalBranchQuota</code>:</p> 4729 {#code_begin|test#} 4730 test "foo" { 4731 comptime { 4732 @setEvalBranchQuota(1001); 4733 var i = 0; 4734 while (i < 1001) : (i += 1) {} 4735 } 4736 } 4737 {#code_end#} 4738 4739 {#see_also|comptime#} 4740 {#header_close#} 4741 {#header_open|@setFloatMode#} 4742 <pre><code class="zig">@setFloatMode(scope, mode: @import("builtin").FloatMode)</code></pre> 4743 <p> 4744 Sets the floating point mode for a given scope. Possible values are: 4745 </p> 4746 {#code_begin|syntax#} 4747 pub const FloatMode = enum { 4748 Optimized, 4749 Strict, 4750 }; 4751 {#code_end#} 4752 <ul> 4753 <li> 4754 <code>Optimized</code> (default) - Floating point operations may do all of the following: 4755 <ul> 4756 <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> 4757 <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> 4758 <li>Treat the sign of a zero argument or result as insignificant.</li> 4759 <li>Use the reciprocal of an argument rather than perform division.</li> 4760 <li>Perform floating-point contraction (e.g. fusing a multiply followed by an addition into a fused multiply-and-add).</li> 4761 <li>Perform algebraically equivalent transformations that may change results in floating point (e.g. reassociate).</li> 4762 </ul> 4763 This is equivalent to <code>-ffast-math</code> in GCC. 4764 </li> 4765 <li> 4766 <code>Strict</code> - Floating point operations follow strict IEEE compliance. 4767 </li> 4768 </ul> 4769 {#see_also|Floating Point Operations#} 4770 {#header_close#} 4771 {#header_open|@setGlobalLinkage#} 4772 <pre><code class="zig">@setGlobalLinkage(global_variable_name, comptime linkage: GlobalLinkage)</code></pre> 4773 <p> 4774 <code>GlobalLinkage</code> can be found with <code>@import("builtin").GlobalLinkage</code>. 4775 </p> 4776 {#see_also|Compile Variables#} 4777 {#header_close#} 4778 {#header_open|@setGlobalSection#} 4779 <pre><code class="zig">@setGlobalSection(global_variable_name, comptime section_name: []const u8) bool</code></pre> 4780 <p> 4781 Puts the global variable in the specified section. 4782 </p> 4783 {#header_close#} 4784 {#header_open|@shlExact#} 4785 <pre><code class="zig">@shlExact(value: T, shift_amt: Log2T) T</code></pre> 4786 <p> 4787 Performs the left shift operation (<code><<</code>). Caller guarantees 4788 that the shift will not shift any 1 bits out. 4789 </p> 4790 <p> 4791 The type of <code>shift_amt</code> is an unsigned integer with <code>log2(T.bit_count)</code> bits. 4792 This is because <code>shift_amt >= T.bit_count</code> is undefined behavior. 4793 </p> 4794 {#see_also|@shrExact|@shlWithOverflow#} 4795 {#header_close#} 4796 {#header_open|@shlWithOverflow#} 4797 <pre><code class="zig">@shlWithOverflow(comptime T: type, a: T, shift_amt: Log2T, result: *T) bool</code></pre> 4798 <p> 4799 Performs <code>result.* = a << b</code>. If overflow or underflow occurs, 4800 stores the overflowed bits in <code>result</code> and returns <code>true</code>. 4801 If no overflow or underflow occurs, returns <code>false</code>. 4802 </p> 4803 <p> 4804 The type of <code>shift_amt</code> is an unsigned integer with <code>log2(T.bit_count)</code> bits. 4805 This is because <code>shift_amt >= T.bit_count</code> is undefined behavior. 4806 </p> 4807 {#see_also|@shlExact|@shrExact#} 4808 {#header_close#} 4809 {#header_open|@shrExact#} 4810 <pre><code class="zig">@shrExact(value: T, shift_amt: Log2T) T</code></pre> 4811 <p> 4812 Performs the right shift operation (<code>>></code>). Caller guarantees 4813 that the shift will not shift any 1 bits out. 4814 </p> 4815 <p> 4816 The type of <code>shift_amt</code> is an unsigned integer with <code>log2(T.bit_count)</code> bits. 4817 This is because <code>shift_amt >= T.bit_count</code> is undefined behavior. 4818 </p> 4819 {#see_also|@shlExact|@shlWithOverflow#} 4820 {#header_close#} 4821 {#header_open|@sizeOf#} 4822 <pre><code class="zig">@sizeOf(comptime T: type) (number literal)</code></pre> 4823 <p> 4824 This function returns the number of bytes it takes to store <code>T</code> in memory. 4825 </p> 4826 <p> 4827 The result is a target-specific compile time constant. 4828 </p> 4829 {#header_close#} 4830 {#header_open|@sqrt#} 4831 <pre><code class="zig">@sqrt(comptime T: type, value: T) T</code></pre> 4832 <p> 4833 Performs the square root of a floating point number. Uses a dedicated hardware instruction 4834 when available. Currently only supports f32 and f64 at runtime. f128 at runtime is TODO. 4835 </p> 4836 <p> 4837 This is a low-level intrinsic. Most code can use <code>std.math.sqrt</code> instead. 4838 </p> 4839 {#header_close#} 4840 {#header_open|@subWithOverflow#} 4841 <pre><code class="zig">@subWithOverflow(comptime T: type, a: T, b: T, result: *T) bool</code></pre> 4842 <p> 4843 Performs <code>result.* = a - b</code>. If overflow or underflow occurs, 4844 stores the overflowed bits in <code>result</code> and returns <code>true</code>. 4845 If no overflow or underflow occurs, returns <code>false</code>. 4846 </p> 4847 {#header_close#} 4848 {#header_open|@truncate#} 4849 <pre><code class="zig">@truncate(comptime T: type, integer) T</code></pre> 4850 <p> 4851 This function truncates bits from an integer type, resulting in a smaller 4852 integer type. 4853 </p> 4854 <p> 4855 The following produces a crash in debug mode and undefined behavior in 4856 release mode: 4857 </p> 4858 <pre><code class="zig">const a: u16 = 0xabcd; 4859 const b: u8 = u8(a);</code></pre> 4860 <p> 4861 However this is well defined and working code: 4862 </p> 4863 <pre><code class="zig">const a: u16 = 0xabcd; 4864 const b: u8 = @truncate(u8, a); 4865 // b is now 0xcd</code></pre> 4866 <p> 4867 This function always truncates the significant bits of the integer, regardless 4868 of endianness on the target platform. 4869 </p> 4870 4871 {#header_close#} 4872 {#header_open|@typeId#} 4873 <pre><code class="zig">@typeId(comptime T: type) @import("builtin").TypeId</code></pre> 4874 <p> 4875 Returns which kind of type something is. Possible values: 4876 </p> 4877 {#code_begin|syntax#} 4878 pub const TypeId = enum { 4879 Type, 4880 Void, 4881 Bool, 4882 NoReturn, 4883 Int, 4884 Float, 4885 Pointer, 4886 Array, 4887 Struct, 4888 FloatLiteral, 4889 IntLiteral, 4890 UndefinedLiteral, 4891 NullLiteral, 4892 Nullable, 4893 ErrorUnion, 4894 Error, 4895 Enum, 4896 Union, 4897 Fn, 4898 Namespace, 4899 Block, 4900 BoundFn, 4901 ArgTuple, 4902 Opaque, 4903 }; 4904 {#code_end#} 4905 {#header_close#} 4906 {#header_open|@typeInfo#} 4907 <pre><code class="zig">@typeInfo(comptime T: type) @import("builtin").TypeInfo</code></pre> 4908 <p> 4909 Returns information on the type. Returns a value of the following union: 4910 </p> 4911 {#code_begin|syntax#} 4912 pub const TypeInfo = union(TypeId) { 4913 Type: void, 4914 Void: void, 4915 Bool: void, 4916 NoReturn: void, 4917 Int: Int, 4918 Float: Float, 4919 Pointer: Pointer, 4920 Array: Array, 4921 Struct: Struct, 4922 FloatLiteral: void, 4923 IntLiteral: void, 4924 UndefinedLiteral: void, 4925 NullLiteral: void, 4926 Nullable: Nullable, 4927 ErrorUnion: ErrorUnion, 4928 ErrorSet: ErrorSet, 4929 Enum: Enum, 4930 Union: Union, 4931 Fn: Fn, 4932 Namespace: void, 4933 Block: void, 4934 BoundFn: Fn, 4935 ArgTuple: void, 4936 Opaque: void, 4937 Promise: Promise, 4938 4939 4940 pub const Int = struct { 4941 is_signed: bool, 4942 bits: u8, 4943 }; 4944 4945 pub const Float = struct { 4946 bits: u8, 4947 }; 4948 4949 pub const Pointer = struct { 4950 is_const: bool, 4951 is_volatile: bool, 4952 alignment: u32, 4953 child: type, 4954 }; 4955 4956 pub const Array = struct { 4957 len: usize, 4958 child: type, 4959 }; 4960 4961 pub const ContainerLayout = enum { 4962 Auto, 4963 Extern, 4964 Packed, 4965 }; 4966 4967 pub const StructField = struct { 4968 name: []const u8, 4969 offset: ?usize, 4970 field_type: type, 4971 }; 4972 4973 pub const Struct = struct { 4974 layout: ContainerLayout, 4975 fields: []StructField, 4976 defs: []Definition, 4977 }; 4978 4979 pub const Nullable = struct { 4980 child: type, 4981 }; 4982 4983 pub const ErrorUnion = struct { 4984 error_set: type, 4985 payload: type, 4986 }; 4987 4988 pub const Error = struct { 4989 name: []const u8, 4990 value: usize, 4991 }; 4992 4993 pub const ErrorSet = struct { 4994 errors: []Error, 4995 }; 4996 4997 pub const EnumField = struct { 4998 name: []const u8, 4999 value: usize, 5000 }; 5001 5002 pub const Enum = struct { 5003 layout: ContainerLayout, 5004 tag_type: type, 5005 fields: []EnumField, 5006 defs: []Definition, 5007 }; 5008 5009 pub const UnionField = struct { 5010 name: []const u8, 5011 enum_field: ?EnumField, 5012 field_type: type, 5013 }; 5014 5015 pub const Union = struct { 5016 layout: ContainerLayout, 5017 tag_type: type, 5018 fields: []UnionField, 5019 defs: []Definition, 5020 }; 5021 5022 pub const CallingConvention = enum { 5023 Unspecified, 5024 C, 5025 Cold, 5026 Naked, 5027 Stdcall, 5028 Async, 5029 }; 5030 5031 pub const FnArg = struct { 5032 is_generic: bool, 5033 is_noalias: bool, 5034 arg_type: type, 5035 }; 5036 5037 pub const Fn = struct { 5038 calling_convention: CallingConvention, 5039 is_generic: bool, 5040 is_var_args: bool, 5041 return_type: type, 5042 async_allocator_type: type, 5043 args: []FnArg, 5044 }; 5045 5046 pub const Promise = struct { 5047 child: type, 5048 }; 5049 5050 pub const Definition = struct { 5051 name: []const u8, 5052 is_pub: bool, 5053 data: Data, 5054 5055 pub const Data = union(enum) { 5056 Type: type, 5057 Var: type, 5058 Fn: FnDef, 5059 5060 pub const FnDef = struct { 5061 fn_type: type, 5062 inline_type: Inline, 5063 calling_convention: CallingConvention, 5064 is_var_args: bool, 5065 is_extern: bool, 5066 is_export: bool, 5067 lib_name: ?[]const u8, 5068 return_type: type, 5069 arg_names: [][] const u8, 5070 5071 pub const Inline = enum { 5072 Auto, 5073 Always, 5074 Never, 5075 }; 5076 }; 5077 }; 5078 }; 5079 }; 5080 {#code_end#} 5081 {#header_close#} 5082 {#header_open|@typeName#} 5083 <pre><code class="zig">@typeName(T: type) []u8</code></pre> 5084 <p> 5085 This function returns the string representation of a type. 5086 </p> 5087 5088 {#header_close#} 5089 {#header_open|@typeOf#} 5090 <pre><code class="zig">@typeOf(expression) type</code></pre> 5091 <p> 5092 This function returns a compile-time constant, which is the type of the 5093 expression passed as an argument. The expression is evaluated. 5094 </p> 5095 5096 {#header_close#} 5097 {#header_close#} 5098 {#header_open|Build Mode#} 5099 <p> 5100 Zig has three build modes: 5101 </p> 5102 <ul> 5103 <li>{#link|Debug#} (default)</li> 5104 <li>{#link|ReleaseFast#}</li> 5105 <li>{#link|ReleaseSafe#}</li> 5106 </ul> 5107 <p> 5108 To add standard build options to a <code>build.zig</code> file: 5109 </p> 5110 {#code_begin|syntax#} 5111 const Builder = @import("std").build.Builder; 5112 5113 pub fn build(b: &Builder) void { 5114 const exe = b.addExecutable("example", "example.zig"); 5115 exe.setBuildMode(b.standardReleaseOptions()); 5116 b.default_step.dependOn(&exe.step); 5117 } 5118 {#code_end#} 5119 <p> 5120 This causes these options to be available: 5121 </p> 5122 <pre><code class="shell"> -Drelease-safe=(bool) optimizations on and safety on 5123 -Drelease-fast=(bool) optimizations on and safety off</code></pre> 5124 {#header_open|Debug#} 5125 <pre><code class="shell">$ zig build-exe example.zig</code></pre> 5126 <ul> 5127 <li>Fast compilation speed</li> 5128 <li>Safety checks enabled</li> 5129 <li>Slow runtime performance</li> 5130 </ul> 5131 {#header_close#} 5132 {#header_open|ReleaseFast#} 5133 <pre><code class="shell">$ zig build-exe example.zig --release-fast</code></pre> 5134 <ul> 5135 <li>Fast runtime performance</li> 5136 <li>Safety checks disabled</li> 5137 <li>Slow compilation speed</li> 5138 </ul> 5139 {#header_close#} 5140 {#header_open|ReleaseSafe#} 5141 <pre><code class="shell">$ zig build-exe example.zig --release-safe</code></pre> 5142 <ul> 5143 <li>Medium runtime performance</li> 5144 <li>Safety checks enabled</li> 5145 <li>Slow compilation speed</li> 5146 </ul> 5147 {#see_also|Compile Variables|Zig Build System|Undefined Behavior#} 5148 {#header_close#} 5149 {#header_close#} 5150 {#header_open|Undefined Behavior#} 5151 <p> 5152 Zig has many instances of undefined behavior. If undefined behavior is 5153 detected at compile-time, Zig emits an error. Most undefined behavior that 5154 cannot be detected at compile-time can be detected at runtime. In these cases, 5155 Zig has safety checks. Safety checks can be disabled on a per-block basis 5156 with <code>@setRuntimeSafety</code>. The {#link|ReleaseFast#} 5157 build mode disables all safety checks in order to facilitate optimizations. 5158 </p> 5159 <p> 5160 When a safety check fails, Zig crashes with a stack trace, like this: 5161 </p> 5162 {#code_begin|test_err|reached unreachable code#} 5163 test "safety check" { 5164 unreachable; 5165 } 5166 {#code_end#} 5167 {#header_open|Reaching Unreachable Code#} 5168 <p>At compile-time:</p> 5169 {#code_begin|test_err|unable to evaluate constant expression#} 5170 comptime { 5171 assert(false); 5172 } 5173 fn assert(ok: bool) void { 5174 if (!ok) unreachable; // assertion failure 5175 } 5176 {#code_end#} 5177 <p>At runtime crashes with the message <code>reached unreachable code</code> and a stack trace.</p> 5178 {#header_close#} 5179 {#header_open|Index out of Bounds#} 5180 <p>At compile-time:</p> 5181 {#code_begin|test_err|index 5 outside array of size 5#} 5182 comptime { 5183 const array = "hello"; 5184 const garbage = array[5]; 5185 } 5186 {#code_end#} 5187 <p>At runtime crashes with the message <code>index out of bounds</code> and a stack trace.</p> 5188 {#header_close#} 5189 {#header_open|Cast Negative Number to Unsigned Integer#} 5190 <p>At compile-time:</p> 5191 {#code_begin|test_err|attempt to cast negative value to unsigned integer#} 5192 comptime { 5193 const value: i32 = -1; 5194 const unsigned = u32(value); 5195 } 5196 {#code_end#} 5197 <p>At runtime crashes with the message <code>attempt to cast negative value to unsigned integer</code> and a stack trace.</p> 5198 <p> 5199 If you are trying to obtain the maximum value of an unsigned integer, use <code>@maxValue(T)</code>, 5200 where <code>T</code> is the integer type, such as <code>u32</code>. 5201 </p> 5202 {#header_close#} 5203 {#header_open|Cast Truncates Data#} 5204 <p>At compile-time:</p> 5205 {#code_begin|test_err|cast from 'u16' to 'u8' truncates bits#} 5206 comptime { 5207 const spartan_count: u16 = 300; 5208 const byte = u8(spartan_count); 5209 } 5210 {#code_end#} 5211 <p>At runtime crashes with the message <code>integer cast truncated bits</code> and a stack trace.</p> 5212 <p> 5213 If you are trying to truncate bits, use <code>@truncate(T, value)</code>, 5214 where <code>T</code> is the integer type, such as <code>u32</code>, and <code>value</code> 5215 is the value you want to truncate. 5216 </p> 5217 {#header_close#} 5218 {#header_open|Integer Overflow#} 5219 {#header_open|Default Operations#} 5220 <p>The following operators can cause integer overflow:</p> 5221 <ul> 5222 <li><code>+</code> (addition)</li> 5223 <li><code>-</code> (subtraction)</li> 5224 <li><code>-</code> (negation)</li> 5225 <li><code>*</code> (multiplication)</li> 5226 <li><code>/</code> (division)</li> 5227 <li><code>@divTrunc</code> (division)</li> 5228 <li><code>@divFloor</code> (division)</li> 5229 <li><code>@divExact</code> (division)</li> 5230 </ul> 5231 <p>Example with addition at compile-time:</p> 5232 {#code_begin|test_err|operation caused overflow#} 5233 comptime { 5234 var byte: u8 = 255; 5235 byte += 1; 5236 } 5237 {#code_end#} 5238 <p>At runtime crashes with the message <code>integer overflow</code> and a stack trace.</p> 5239 {#header_close#} 5240 {#header_open|Standard Library Math Functions#} 5241 <p>These functions provided by the standard library return possible errors.</p> 5242 <ul> 5243 <li><code>@import("std").math.add</code></li> 5244 <li><code>@import("std").math.sub</code></li> 5245 <li><code>@import("std").math.mul</code></li> 5246 <li><code>@import("std").math.divTrunc</code></li> 5247 <li><code>@import("std").math.divFloor</code></li> 5248 <li><code>@import("std").math.divExact</code></li> 5249 <li><code>@import("std").math.shl</code></li> 5250 </ul> 5251 <p>Example of catching an overflow for addition:</p> 5252 {#code_begin|exe_err#} 5253 const math = @import("std").math; 5254 const warn = @import("std").debug.warn; 5255 pub fn main() !void { 5256 var byte: u8 = 255; 5257 5258 byte = if (math.add(u8, byte, 1)) |result| result else |err| { 5259 warn("unable to add one: {}\n", @errorName(err)); 5260 return err; 5261 }; 5262 5263 warn("result: {}\n", byte); 5264 } 5265 {#code_end#} 5266 {#header_close#} 5267 {#header_open|Builtin Overflow Functions#} 5268 <p> 5269 These builtins return a <code>bool</code> of whether or not overflow 5270 occurred, as well as returning the overflowed bits: 5271 </p> 5272 <ul> 5273 <li><code>@addWithOverflow</code></li> 5274 <li><code>@subWithOverflow</code></li> 5275 <li><code>@mulWithOverflow</code></li> 5276 <li><code>@shlWithOverflow</code></li> 5277 </ul> 5278 <p> 5279 Example of <code>@addWithOverflow</code>: 5280 </p> 5281 {#code_begin|exe#} 5282 const warn = @import("std").debug.warn; 5283 pub fn main() void { 5284 var byte: u8 = 255; 5285 5286 var result: u8 = undefined; 5287 if (@addWithOverflow(u8, byte, 10, &result)) { 5288 warn("overflowed result: {}\n", result); 5289 } else { 5290 warn("result: {}\n", result); 5291 } 5292 } 5293 {#code_end#} 5294 {#header_close#} 5295 {#header_open|Wrapping Operations#} 5296 <p> 5297 These operations have guaranteed wraparound semantics. 5298 </p> 5299 <ul> 5300 <li><code>+%</code> (wraparound addition)</li> 5301 <li><code>-%</code> (wraparound subtraction)</li> 5302 <li><code>-%</code> (wraparound negation)</li> 5303 <li><code>*%</code> (wraparound multiplication)</li> 5304 </ul> 5305 {#code_begin|test#} 5306 const assert = @import("std").debug.assert; 5307 5308 test "wraparound addition and subtraction" { 5309 const x: i32 = @maxValue(i32); 5310 const min_val = x +% 1; 5311 assert(min_val == @minValue(i32)); 5312 const max_val = min_val -% 1; 5313 assert(max_val == @maxValue(i32)); 5314 } 5315 {#code_end#} 5316 {#header_close#} 5317 {#header_close#} 5318 {#header_open|Exact Left Shift Overflow#} 5319 <p>At compile-time:</p> 5320 {#code_begin|test_err|operation caused overflow#} 5321 comptime { 5322 const x = @shlExact(u8(0b01010101), 2); 5323 } 5324 {#code_end#} 5325 <p>At runtime crashes with the message <code>left shift overflowed bits</code> and a stack trace.</p> 5326 {#header_close#} 5327 {#header_open|Exact Right Shift Overflow#} 5328 <p>At compile-time:</p> 5329 {#code_begin|test_err|exact shift shifted out 1 bits#} 5330 comptime { 5331 const x = @shrExact(u8(0b10101010), 2); 5332 } 5333 {#code_end#} 5334 <p>At runtime crashes with the message <code>right shift overflowed bits</code> and a stack trace.</p> 5335 {#header_close#} 5336 {#header_open|Division by Zero#} 5337 <p>At compile-time:</p> 5338 {#code_begin|test_err|division by zero#} 5339 comptime { 5340 const a: i32 = 1; 5341 const b: i32 = 0; 5342 const c = a / b; 5343 } 5344 {#code_end#} 5345 <p>At runtime crashes with the message <code>division by zero</code> and a stack trace.</p> 5346 5347 {#header_close#} 5348 {#header_open|Remainder Division by Zero#} 5349 <p>At compile-time:</p> 5350 {#code_begin|test_err|division by zero#} 5351 comptime { 5352 const a: i32 = 10; 5353 const b: i32 = 0; 5354 const c = a % b; 5355 } 5356 {#code_end#} 5357 <p>At runtime crashes with the message <code>remainder division by zero</code> and a stack trace.</p> 5358 5359 {#header_close#} 5360 {#header_open|Exact Division Remainder#} 5361 <p>TODO</p> 5362 {#header_close#} 5363 {#header_open|Slice Widen Remainder#} 5364 <p>TODO</p> 5365 {#header_close#} 5366 {#header_open|Attempt to Unwrap Null#} 5367 <p>At compile-time:</p> 5368 {#code_begin|test_err|unable to unwrap null#} 5369 comptime { 5370 const nullable_number: ?i32 = null; 5371 const number = ??nullable_number; 5372 } 5373 {#code_end#} 5374 <p>At runtime crashes with the message <code>attempt to unwrap null</code> and a stack trace.</p> 5375 <p>One way to avoid this crash is to test for null instead of assuming non-null, with 5376 the <code>if</code> expression:</p> 5377 {#code_begin|exe|test#} 5378 const warn = @import("std").debug.warn; 5379 pub fn main() void { 5380 const nullable_number: ?i32 = null; 5381 5382 if (nullable_number) |number| { 5383 warn("got number: {}\n", number); 5384 } else { 5385 warn("it's null\n"); 5386 } 5387 } 5388 {#code_end#} 5389 {#header_close#} 5390 {#header_open|Attempt to Unwrap Error#} 5391 <p>At compile-time:</p> 5392 {#code_begin|test_err|caught unexpected error 'UnableToReturnNumber'#} 5393 comptime { 5394 const number = getNumberOrFail() catch unreachable; 5395 } 5396 5397 fn getNumberOrFail() !i32 { 5398 return error.UnableToReturnNumber; 5399 } 5400 {#code_end#} 5401 <p>At runtime crashes with the message <code>attempt to unwrap error: ErrorCode</code> and a stack trace.</p> 5402 <p>One way to avoid this crash is to test for an error instead of assuming a successful result, with 5403 the <code>if</code> expression:</p> 5404 {#code_begin|exe#} 5405 const warn = @import("std").debug.warn; 5406 5407 pub fn main() void { 5408 const result = getNumberOrFail(); 5409 5410 if (result) |number| { 5411 warn("got number: {}\n", number); 5412 } else |err| { 5413 warn("got error: {}\n", @errorName(err)); 5414 } 5415 } 5416 5417 fn getNumberOrFail() !i32 { 5418 return error.UnableToReturnNumber; 5419 } 5420 {#code_end#} 5421 {#header_close#} 5422 {#header_open|Invalid Error Code#} 5423 <p>At compile-time:</p> 5424 {#code_begin|test_err|integer value 11 represents no error#} 5425 comptime { 5426 const err = error.AnError; 5427 const number = u32(err) + 10; 5428 const invalid_err = error(number); 5429 } 5430 {#code_end#} 5431 <p>At runtime crashes with the message <code>invalid error code</code> and a stack trace.</p> 5432 {#header_close#} 5433 {#header_open|Invalid Enum Cast#} 5434 <p>TODO</p> 5435 5436 {#header_close#} 5437 {#header_open|Incorrect Pointer Alignment#} 5438 <p>TODO</p> 5439 5440 {#header_close#} 5441 {#header_open|Wrong Union Field Access#} 5442 <p>TODO</p> 5443 5444 {#header_close#} 5445 {#header_close#} 5446 {#header_open|Memory#} 5447 <p>TODO: explain no default allocator in zig</p> 5448 <p>TODO: show how to use the allocator interface</p> 5449 <p>TODO: mention debug allocator</p> 5450 <p>TODO: importance of checking for allocation failure</p> 5451 <p>TODO: mention overcommit and the OOM Killer</p> 5452 <p>TODO: mention recursion</p> 5453 {#see_also|Pointers#} 5454 5455 {#header_close#} 5456 {#header_open|Compile Variables#} 5457 <p> 5458 Compile variables are accessible by importing the <code>"builtin"</code> package, 5459 which the compiler makes available to every Zig source file. It contains 5460 compile-time constants such as the current target, endianness, and release mode. 5461 </p> 5462 {#code_begin|syntax#} 5463 const builtin = @import("builtin"); 5464 const separator = if (builtin.os == builtin.Os.windows) '\\' else '/'; 5465 {#code_end#} 5466 <p> 5467 Example of what is imported with <code>@import("builtin")</code>: 5468 </p> 5469 {#code_begin|syntax#} 5470 pub const StackTrace = struct { 5471 index: usize, 5472 instruction_addresses: []usize, 5473 }; 5474 5475 pub const Os = enum { 5476 freestanding, 5477 ananas, 5478 cloudabi, 5479 dragonfly, 5480 freebsd, 5481 fuchsia, 5482 ios, 5483 kfreebsd, 5484 linux, 5485 lv2, 5486 macosx, 5487 netbsd, 5488 openbsd, 5489 solaris, 5490 windows, 5491 haiku, 5492 minix, 5493 rtems, 5494 nacl, 5495 cnk, 5496 aix, 5497 cuda, 5498 nvcl, 5499 amdhsa, 5500 ps4, 5501 elfiamcu, 5502 tvos, 5503 watchos, 5504 mesa3d, 5505 contiki, 5506 amdpal, 5507 zen, 5508 }; 5509 5510 pub const Arch = enum { 5511 armv8_3a, 5512 armv8_2a, 5513 armv8_1a, 5514 armv8, 5515 armv8r, 5516 armv8m_baseline, 5517 armv8m_mainline, 5518 armv7, 5519 armv7em, 5520 armv7m, 5521 armv7s, 5522 armv7k, 5523 armv7ve, 5524 armv6, 5525 armv6m, 5526 armv6k, 5527 armv6t2, 5528 armv5, 5529 armv5te, 5530 armv4t, 5531 armebv8_3a, 5532 armebv8_2a, 5533 armebv8_1a, 5534 armebv8, 5535 armebv8r, 5536 armebv8m_baseline, 5537 armebv8m_mainline, 5538 armebv7, 5539 armebv7em, 5540 armebv7m, 5541 armebv7s, 5542 armebv7k, 5543 armebv7ve, 5544 armebv6, 5545 armebv6m, 5546 armebv6k, 5547 armebv6t2, 5548 armebv5, 5549 armebv5te, 5550 armebv4t, 5551 aarch64, 5552 aarch64_be, 5553 arc, 5554 avr, 5555 bpfel, 5556 bpfeb, 5557 hexagon, 5558 mips, 5559 mipsel, 5560 mips64, 5561 mips64el, 5562 msp430, 5563 nios2, 5564 powerpc, 5565 powerpc64, 5566 powerpc64le, 5567 r600, 5568 amdgcn, 5569 riscv32, 5570 riscv64, 5571 sparc, 5572 sparcv9, 5573 sparcel, 5574 s390x, 5575 tce, 5576 tcele, 5577 thumb, 5578 thumbeb, 5579 i386, 5580 x86_64, 5581 xcore, 5582 nvptx, 5583 nvptx64, 5584 le32, 5585 le64, 5586 amdil, 5587 amdil64, 5588 hsail, 5589 hsail64, 5590 spir, 5591 spir64, 5592 kalimbav3, 5593 kalimbav4, 5594 kalimbav5, 5595 shave, 5596 lanai, 5597 wasm32, 5598 wasm64, 5599 renderscript32, 5600 renderscript64, 5601 }; 5602 5603 pub const Environ = enum { 5604 unknown, 5605 gnu, 5606 gnuabin32, 5607 gnuabi64, 5608 gnueabi, 5609 gnueabihf, 5610 gnux32, 5611 code16, 5612 eabi, 5613 eabihf, 5614 android, 5615 musl, 5616 musleabi, 5617 musleabihf, 5618 msvc, 5619 itanium, 5620 cygnus, 5621 amdopencl, 5622 coreclr, 5623 opencl, 5624 simulator, 5625 }; 5626 5627 pub const ObjectFormat = enum { 5628 unknown, 5629 coff, 5630 elf, 5631 macho, 5632 wasm, 5633 }; 5634 5635 pub const GlobalLinkage = enum { 5636 Internal, 5637 Strong, 5638 Weak, 5639 LinkOnce, 5640 }; 5641 5642 pub const AtomicOrder = enum { 5643 Unordered, 5644 Monotonic, 5645 Acquire, 5646 Release, 5647 AcqRel, 5648 SeqCst, 5649 }; 5650 5651 pub const AtomicRmwOp = enum { 5652 Xchg, 5653 Add, 5654 Sub, 5655 And, 5656 Nand, 5657 Or, 5658 Xor, 5659 Max, 5660 Min, 5661 }; 5662 5663 pub const Mode = enum { 5664 Debug, 5665 ReleaseSafe, 5666 ReleaseFast, 5667 ReleaseSmall, 5668 }; 5669 5670 pub const TypeId = enum { 5671 Type, 5672 Void, 5673 Bool, 5674 NoReturn, 5675 Int, 5676 Float, 5677 Pointer, 5678 Array, 5679 Struct, 5680 FloatLiteral, 5681 IntLiteral, 5682 UndefinedLiteral, 5683 NullLiteral, 5684 Nullable, 5685 ErrorUnion, 5686 ErrorSet, 5687 Enum, 5688 Union, 5689 Fn, 5690 Namespace, 5691 Block, 5692 BoundFn, 5693 ArgTuple, 5694 Opaque, 5695 Promise, 5696 }; 5697 5698 pub const TypeInfo = union(TypeId) { 5699 Type: void, 5700 Void: void, 5701 Bool: void, 5702 NoReturn: void, 5703 Int: Int, 5704 Float: Float, 5705 Pointer: Pointer, 5706 Array: Array, 5707 Struct: Struct, 5708 FloatLiteral: void, 5709 IntLiteral: void, 5710 UndefinedLiteral: void, 5711 NullLiteral: void, 5712 Nullable: Nullable, 5713 ErrorUnion: ErrorUnion, 5714 ErrorSet: ErrorSet, 5715 Enum: Enum, 5716 Union: Union, 5717 Fn: Fn, 5718 Namespace: void, 5719 Block: void, 5720 BoundFn: Fn, 5721 ArgTuple: void, 5722 Opaque: void, 5723 Promise: Promise, 5724 5725 5726 pub const Int = struct { 5727 is_signed: bool, 5728 bits: u8, 5729 }; 5730 5731 pub const Float = struct { 5732 bits: u8, 5733 }; 5734 5735 pub const Pointer = struct { 5736 is_const: bool, 5737 is_volatile: bool, 5738 alignment: u32, 5739 child: type, 5740 }; 5741 5742 pub const Array = struct { 5743 len: usize, 5744 child: type, 5745 }; 5746 5747 pub const ContainerLayout = enum { 5748 Auto, 5749 Extern, 5750 Packed, 5751 }; 5752 5753 pub const StructField = struct { 5754 name: []const u8, 5755 offset: ?usize, 5756 field_type: type, 5757 }; 5758 5759 pub const Struct = struct { 5760 layout: ContainerLayout, 5761 fields: []StructField, 5762 defs: []Definition, 5763 }; 5764 5765 pub const Nullable = struct { 5766 child: type, 5767 }; 5768 5769 pub const ErrorUnion = struct { 5770 error_set: type, 5771 payload: type, 5772 }; 5773 5774 pub const Error = struct { 5775 name: []const u8, 5776 value: usize, 5777 }; 5778 5779 pub const ErrorSet = struct { 5780 errors: []Error, 5781 }; 5782 5783 pub const EnumField = struct { 5784 name: []const u8, 5785 value: usize, 5786 }; 5787 5788 pub const Enum = struct { 5789 layout: ContainerLayout, 5790 tag_type: type, 5791 fields: []EnumField, 5792 defs: []Definition, 5793 }; 5794 5795 pub const UnionField = struct { 5796 name: []const u8, 5797 enum_field: ?EnumField, 5798 field_type: type, 5799 }; 5800 5801 pub const Union = struct { 5802 layout: ContainerLayout, 5803 tag_type: type, 5804 fields: []UnionField, 5805 defs: []Definition, 5806 }; 5807 5808 pub const CallingConvention = enum { 5809 Unspecified, 5810 C, 5811 Cold, 5812 Naked, 5813 Stdcall, 5814 Async, 5815 }; 5816 5817 pub const FnArg = struct { 5818 is_generic: bool, 5819 is_noalias: bool, 5820 arg_type: type, 5821 }; 5822 5823 pub const Fn = struct { 5824 calling_convention: CallingConvention, 5825 is_generic: bool, 5826 is_var_args: bool, 5827 return_type: type, 5828 async_allocator_type: type, 5829 args: []FnArg, 5830 }; 5831 5832 pub const Promise = struct { 5833 child: type, 5834 }; 5835 5836 pub const Definition = struct { 5837 name: []const u8, 5838 is_pub: bool, 5839 data: Data, 5840 5841 pub const Data = union(enum) { 5842 Type: type, 5843 Var: type, 5844 Fn: FnDef, 5845 5846 pub const FnDef = struct { 5847 fn_type: type, 5848 inline_type: Inline, 5849 calling_convention: CallingConvention, 5850 is_var_args: bool, 5851 is_extern: bool, 5852 is_export: bool, 5853 lib_name: ?[]const u8, 5854 return_type: type, 5855 arg_names: [][] const u8, 5856 5857 pub const Inline = enum { 5858 Auto, 5859 Always, 5860 Never, 5861 }; 5862 }; 5863 }; 5864 }; 5865 }; 5866 5867 pub const FloatMode = enum { 5868 Optimized, 5869 Strict, 5870 }; 5871 5872 pub const Endian = enum { 5873 Big, 5874 Little, 5875 }; 5876 5877 pub const endian = Endian.Little; 5878 pub const is_test = true; 5879 pub const os = Os.linux; 5880 pub const arch = Arch.x86_64; 5881 pub const environ = Environ.gnu; 5882 pub const object_format = ObjectFormat.elf; 5883 pub const mode = Mode.Debug; 5884 pub const link_libc = false; 5885 pub const have_error_return_tracing = true; 5886 pub const __zig_test_fn_slice = {}; // overwritten later 5887 {#code_end#} 5888 {#see_also|Build Mode#} 5889 {#header_close#} 5890 {#header_open|Root Source File#} 5891 <p>TODO: explain how root source file finds other files</p> 5892 <p>TODO: pub fn main</p> 5893 <p>TODO: pub fn panic</p> 5894 <p>TODO: if linking with libc you can use export fn main</p> 5895 <p>TODO: order independent top level declarations</p> 5896 <p>TODO: lazy analysis</p> 5897 <p>TODO: using comptime { _ = @import() }</p> 5898 {#header_close#} 5899 {#header_open|Zig Test#} 5900 <p>TODO: basic usage</p> 5901 <p>TODO: lazy analysis</p> 5902 <p>TODO: --test-filter</p> 5903 <p>TODO: --test-name-prefix</p> 5904 <p>TODO: testing in releasefast and releasesafe mode. assert still works</p> 5905 {#header_close#} 5906 {#header_open|Zig Build System#} 5907 <p>TODO: explain purpose, it's supposed to replace make/cmake</p> 5908 <p>TODO: example of building a zig executable</p> 5909 <p>TODO: example of building a C library</p> 5910 {#header_close#} 5911 {#header_open|C#} 5912 <p> 5913 Although Zig is independent of C, and, unlike most other languages, does not depend on libc, 5914 Zig acknowledges the importance of interacting with existing C code. 5915 </p> 5916 <p> 5917 There are a few ways that Zig facilitates C interop. 5918 </p> 5919 {#header_open|C Type Primitives#} 5920 <p> 5921 These have guaranteed C ABI compatibility and can be used like any other type. 5922 </p> 5923 <ul> 5924 <li><code>c_short</code></li> 5925 <li><code>c_ushort</code></li> 5926 <li><code>c_int</code></li> 5927 <li><code>c_uint</code></li> 5928 <li><code>c_long</code></li> 5929 <li><code>c_ulong</code></li> 5930 <li><code>c_longlong</code></li> 5931 <li><code>c_ulonglong</code></li> 5932 <li><code>c_longdouble</code></li> 5933 <li><code>c_void</code></li> 5934 </ul> 5935 {#see_also|Primitive Types#} 5936 {#header_close#} 5937 {#header_open|C String Literals#} 5938 {#code_begin|exe#} 5939 {#link_libc#} 5940 extern fn puts(*const u8) void; 5941 5942 pub fn main() void { 5943 puts(c"this has a null terminator"); 5944 puts( 5945 c\\and so 5946 c\\does this 5947 c\\multiline C string literal 5948 ); 5949 } 5950 {#code_end#} 5951 {#see_also|String Literals#} 5952 {#header_close#} 5953 {#header_open|Import from C Header File#} 5954 <p> 5955 The <code>@cImport</code> builtin function can be used 5956 to directly import symbols from .h files: 5957 </p> 5958 {#code_begin|exe#} 5959 {#link_libc#} 5960 const c = @cImport({ 5961 // See https://github.com/ziglang/zig/issues/515 5962 @cDefine("_NO_CRT_STDIO_INLINE", "1"); 5963 @cInclude("stdio.h"); 5964 }); 5965 pub fn main() void { 5966 _ = c.printf(c"hello\n"); 5967 } 5968 {#code_end#} 5969 <p> 5970 The <code>@cImport</code> function takes an expression as a parameter. 5971 This expression is evaluated at compile-time and is used to control 5972 preprocessor directives and include multiple .h files: 5973 </p> 5974 {#code_begin|syntax#} 5975 const builtin = @import("builtin"); 5976 5977 const c = @cImport({ 5978 @cDefine("NDEBUG", builtin.mode == builtin.Mode.ReleaseFast); 5979 if (something) { 5980 @cDefine("_GNU_SOURCE", {}); 5981 } 5982 @cInclude("stdlib.h"); 5983 if (something) { 5984 @cUndef("_GNU_SOURCE"); 5985 } 5986 @cInclude("soundio.h"); 5987 }); 5988 {#code_end#} 5989 {#see_also|@cImport|@cInclude|@cDefine|@cUndef|@import#} 5990 {#header_close#} 5991 {#header_open|Mixing Object Files#} 5992 <p> 5993 You can mix Zig object files with any other object files that respect the C ABI. Example: 5994 </p> 5995 <p class="file">base64.zig</p> 5996 {#code_begin|syntax#} 5997 const base64 = @import("std").base64; 5998 5999 export fn decode_base_64(dest_ptr: *u8, dest_len: usize, 6000 source_ptr: *const u8, source_len: usize) usize 6001 { 6002 const src = source_ptr[0..source_len]; 6003 const dest = dest_ptr[0..dest_len]; 6004 const base64_decoder = base64.standard_decoder_unsafe; 6005 const decoded_size = base64_decoder.calcSize(src); 6006 base64_decoder.decode(dest[0..decoded_size], src); 6007 return decoded_size; 6008 } 6009 {#code_end#} 6010 <p class="file">test.c</p> 6011 <pre><code class="cpp">// This header is generated by zig from base64.zig 6012 #include "base64.h" 6013 6014 #include <string.h> 6015 #include <stdio.h> 6016 6017 int main(int argc, char **argv) { 6018 const char *encoded = "YWxsIHlvdXIgYmFzZSBhcmUgYmVsb25nIHRvIHVz"; 6019 char buf[200]; 6020 6021 size_t len = decode_base_64(buf, 200, encoded, strlen(encoded)); 6022 buf[len] = 0; 6023 puts(buf); 6024 6025 return 0; 6026 }</code></pre> 6027 <p class="file">build.zig</p> 6028 {#code_begin|syntax#} 6029 const Builder = @import("std").build.Builder; 6030 6031 pub fn build(b: *Builder) void { 6032 const obj = b.addObject("base64", "base64.zig"); 6033 6034 const exe = b.addCExecutable("test"); 6035 exe.addCompileFlags([][]const u8 { 6036 "-std=c99", 6037 }); 6038 exe.addSourceFile("test.c"); 6039 exe.addObject(obj); 6040 exe.setOutputPath("."); 6041 6042 b.default_step.dependOn(&exe.step); 6043 } 6044 {#code_end#} 6045 {#header_close#} 6046 {#header_open|Terminal#} 6047 <pre><code class="shell">$ zig build 6048 $ ./test 6049 all your base are belong to us</code></pre> 6050 {#see_also|Targets|Zig Build System#} 6051 {#header_close#} 6052 {#header_close#} 6053 {#header_open|Targets#} 6054 <p> 6055 Zig supports generating code for all targets that LLVM supports. Here is 6056 what it looks like to execute <code>zig targets</code> on a Linux x86_64 6057 computer: 6058 </p> 6059 <pre><code class="shell">$ zig targets 6060 Architectures: 6061 armv8_2a 6062 armv8_1a 6063 armv8 6064 armv8r 6065 armv8m_baseline 6066 armv8m_mainline 6067 armv7 6068 armv7em 6069 armv7m 6070 armv7s 6071 armv7k 6072 armv7ve 6073 armv6 6074 armv6m 6075 armv6k 6076 armv6t2 6077 armv5 6078 armv5te 6079 armv4t 6080 armeb 6081 aarch64 6082 aarch64_be 6083 avr 6084 bpfel 6085 bpfeb 6086 hexagon 6087 mips 6088 mipsel 6089 mips64 6090 mips64el 6091 msp430 6092 nios2 6093 powerpc 6094 powerpc64 6095 powerpc64le 6096 r600 6097 amdgcn 6098 riscv32 6099 riscv64 6100 sparc 6101 sparcv9 6102 sparcel 6103 s390x 6104 tce 6105 tcele 6106 thumb 6107 thumbeb 6108 i386 6109 x86_64 (native) 6110 xcore 6111 nvptx 6112 nvptx64 6113 le32 6114 le64 6115 amdil 6116 amdil64 6117 hsail 6118 hsail64 6119 spir 6120 spir64 6121 kalimbav3 6122 kalimbav4 6123 kalimbav5 6124 shave 6125 lanai 6126 wasm32 6127 wasm64 6128 renderscript32 6129 renderscript64 6130 6131 Operating Systems: 6132 freestanding 6133 ananas 6134 cloudabi 6135 dragonfly 6136 freebsd 6137 fuchsia 6138 ios 6139 kfreebsd 6140 linux (native) 6141 lv2 6142 macosx 6143 netbsd 6144 openbsd 6145 solaris 6146 windows 6147 haiku 6148 minix 6149 rtems 6150 nacl 6151 cnk 6152 bitrig 6153 aix 6154 cuda 6155 nvcl 6156 amdhsa 6157 ps4 6158 elfiamcu 6159 tvos 6160 watchos 6161 mesa3d 6162 contiki 6163 zen 6164 6165 Environments: 6166 unknown 6167 gnu (native) 6168 gnuabi64 6169 gnueabi 6170 gnueabihf 6171 gnux32 6172 code16 6173 eabi 6174 eabihf 6175 android 6176 musl 6177 musleabi 6178 musleabihf 6179 msvc 6180 itanium 6181 cygnus 6182 amdopencl 6183 coreclr 6184 opencl</code></pre> 6185 <p> 6186 The Zig Standard Library (<code>@import("std")</code>) has architecture, environment, and operating sytsem 6187 abstractions, and thus takes additional work to support more platforms. It currently supports 6188 Linux x86_64. Not all standard library code requires operating system abstractions, however, 6189 so things such as generic data structures work an all above platforms. 6190 </p> 6191 {#header_close#} 6192 {#header_open|Style Guide#} 6193 <p> 6194 These coding conventions are not enforced by the compiler, but they are shipped in 6195 this documentation along with the compiler in order to provide a point of 6196 reference, should anyone wish to point to an authority on agreed upon Zig 6197 coding style. 6198 </p> 6199 {#header_open|Whitespace#} 6200 <ul> 6201 <li> 6202 4 space indentation 6203 </li> 6204 <li> 6205 Open braces on same line, unless you need to wrap. 6206 </li> 6207 <li>If a list of things is longer than 2, put each item on its own line and 6208 exercise the abilty to put an extra comma at the end. 6209 </li> 6210 <li> 6211 Line length: aim for 100; use common sense. 6212 </li> 6213 </ul> 6214 {#header_close#} 6215 {#header_open|Names#} 6216 <p> 6217 Roughly speaking: <code>camelCaseFunctionName</code>, <code>TitleCaseTypeName</code>, 6218 <code>snake_case_variable_name</code>. More precisely: 6219 </p> 6220 <ul> 6221 <li> 6222 If <code>x</code> is a <code>struct</code> (or an alias of a <code>struct</code>), 6223 then <code>x</code> should be <code>TitleCase</code>. 6224 </li> 6225 <li> 6226 If <code>x</code> otherwise identifies a type, <code>x</code> should have <code>snake_case</code>. 6227 </li> 6228 <li> 6229 If <code>x</code> is callable, and <code>x</code>'s return type is <code>type</code>, then <code>x</code> should be <code>TitleCase</code>. 6230 </li> 6231 <li> 6232 If <code>x</code> is otherwise callable, then <code>x</code> should be <code>camelCase</code>. 6233 </li> 6234 <li> 6235 Otherwise, <code>x</code> should be <code>snake_case</code>. 6236 </li> 6237 </ul> 6238 <p> 6239 Acronyms, initialisms, proper nouns, or any other word that has capitalization 6240 rules in written English are subject to naming conventions just like any other 6241 word. Even acronyms that are only 2 letters long are subject to these 6242 conventions. 6243 </p> 6244 <p> 6245 These are general rules of thumb; if it makes sense to do something different, 6246 do what makes sense. For example, if there is an established convention such as 6247 <code>ENOENT</code>, follow the established convention. 6248 </p> 6249 {#header_close#} 6250 {#header_open|Examples#} 6251 {#code_begin|syntax#} 6252 const namespace_name = @import("dir_name/file_name.zig"); 6253 var global_var: i32 = undefined; 6254 const const_name = 42; 6255 const primitive_type_alias = f32; 6256 const string_alias = []u8; 6257 6258 const StructName = struct {}; 6259 const StructAlias = StructName; 6260 6261 fn functionName(param_name: TypeName) void { 6262 var functionPointer = functionName; 6263 functionPointer(); 6264 functionPointer = otherFunction; 6265 functionPointer(); 6266 } 6267 const functionAlias = functionName; 6268 6269 fn ListTemplateFunction(comptime ChildType: type, comptime fixed_size: usize) type { 6270 return List(ChildType, fixed_size); 6271 } 6272 6273 fn ShortList(comptime T: type, comptime n: usize) type { 6274 return struct { 6275 field_name: [n]T, 6276 fn methodName() void {} 6277 }; 6278 } 6279 6280 // The word XML loses its casing when used in Zig identifiers. 6281 const xml_document = 6282 \\<?xml version="1.0" encoding="UTF-8"?> 6283 \\<document> 6284 \\</document> 6285 ; 6286 const XmlParser = struct {}; 6287 6288 // The initials BE (Big Endian) are just another word in Zig identifier names. 6289 fn readU32Be() u32 {} 6290 {#code_end#} 6291 <p> 6292 See the Zig Standard Library for more examples. 6293 </p> 6294 {#header_close#} 6295 {#header_close#} 6296 {#header_open|Source Encoding#} 6297 <p>Zig source code is encoded in UTF-8. An invalid UTF-8 byte sequence results in a compile error.</p> 6298 <p>Throughout all zig source code (including in comments), some codepoints are never allowed:</p> 6299 <ul> 6300 <li>Ascii control characters, except for U+000a (LF): U+0000 - U+0009, U+000b - U+0001f, U+007f. (Note that Windows line endings (CRLF) are not allowed, and hard tabs are not allowed.)</li> 6301 <li>Non-Ascii Unicode line endings: U+0085 (NEL), U+2028 (LS), U+2029 (PS).</li> 6302 </ul> 6303 <p>The codepoint U+000a (LF) (which is encoded as the single-byte value 0x0a) is the line terminator character. This character always terminates a line of zig source code (except possbly the last line of the file).</p> 6304 <p>For some discussion on the rationale behind these design decisions, see <a href="https://github.com/ziglang/zig/issues/663">issue #663</a></p> 6305 {#header_close#} 6306 {#header_open|Grammar#} 6307 <pre><code class="nohighlight">Root = many(TopLevelItem) EOF 6308 6309 TopLevelItem = CompTimeExpression(Block) | TopLevelDecl | TestDecl 6310 6311 TestDecl = "test" String Block 6312 6313 TopLevelDecl = option("pub") (FnDef | ExternDecl | GlobalVarDecl | UseDecl) 6314 6315 GlobalVarDecl = option("export") VariableDeclaration ";" 6316 6317 LocalVarDecl = option("comptime") VariableDeclaration 6318 6319 VariableDeclaration = ("var" | "const") Symbol option(":" TypeExpr) option("align" "(" Expression ")") option("section" "(" Expression ")") "=" Expression 6320 6321 ContainerMember = (ContainerField | FnDef | GlobalVarDecl) 6322 6323 ContainerField = Symbol option(":" PrefixOpExpression) option("=" PrefixOpExpression) "," 6324 6325 UseDecl = "use" Expression ";" 6326 6327 ExternDecl = "extern" option(String) (FnProto | VariableDeclaration) ";" 6328 6329 FnProto = option("nakedcc" | "stdcallcc" | "extern" | ("async" option("<" Expression ">"))) "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("section" "(" Expression ")") option("!") (TypeExpr | "var") 6330 6331 FnDef = option("inline" | "export") FnProto Block 6332 6333 ParamDeclList = "(" list(ParamDecl, ",") ")" 6334 6335 ParamDecl = option("noalias" | "comptime") option(Symbol ":") (TypeExpr | "var" | "...") 6336 6337 Block = option(Symbol ":") "{" many(Statement) "}" 6338 6339 Statement = LocalVarDecl ";" | Defer(Block) | Defer(Expression) ";" | BlockExpression(Block) | Expression ";" | ";" 6340 6341 TypeExpr = (PrefixOpExpression "!" PrefixOpExpression) | PrefixOpExpression 6342 6343 BlockOrExpression = Block | Expression 6344 6345 Expression = TryExpression | ReturnExpression | BreakExpression | AssignmentExpression | CancelExpression | ResumeExpression 6346 6347 AsmExpression = "asm" option("volatile") "(" String option(AsmOutput) ")" 6348 6349 AsmOutput = ":" list(AsmOutputItem, ",") option(AsmInput) 6350 6351 AsmInput = ":" list(AsmInputItem, ",") option(AsmClobbers) 6352 6353 AsmOutputItem = "[" Symbol "]" String "(" (Symbol | "->" TypeExpr) ")" 6354 6355 AsmInputItem = "[" Symbol "]" String "(" Expression ")" 6356 6357 AsmClobbers= ":" list(String, ",") 6358 6359 UnwrapExpression = BoolOrExpression (UnwrapNullable | UnwrapError) | BoolOrExpression 6360 6361 UnwrapNullable = "??" Expression 6362 6363 UnwrapError = "catch" option("|" Symbol "|") Expression 6364 6365 AssignmentExpression = UnwrapExpression AssignmentOperator UnwrapExpression | UnwrapExpression 6366 6367 AssignmentOperator = "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "<<=" | ">>=" | "&=" | "^=" | "|=" | "*%=" | "+%=" | "-%=" 6368 6369 BlockExpression(body) = Block | IfExpression(body) | IfErrorExpression(body) | TestExpression(body) | WhileExpression(body) | ForExpression(body) | SwitchExpression | CompTimeExpression(body) | SuspendExpression(body) 6370 6371 CompTimeExpression(body) = "comptime" body 6372 6373 SwitchExpression = "switch" "(" Expression ")" "{" many(SwitchProng) "}" 6374 6375 SwitchProng = (list(SwitchItem, ",") | "else") "=>" option("|" option("*") Symbol "|") Expression "," 6376 6377 SwitchItem = Expression | (Expression "..." Expression) 6378 6379 ForExpression(body) = option(Symbol ":") option("inline") "for" "(" Expression ")" option("|" option("*") Symbol option("," Symbol) "|") body option("else" BlockExpression(body)) 6380 6381 BoolOrExpression = BoolAndExpression "or" BoolOrExpression | BoolAndExpression 6382 6383 ReturnExpression = "return" option(Expression) 6384 6385 TryExpression = "try" Expression 6386 6387 AwaitExpression = "await" Expression 6388 6389 BreakExpression = "break" option(":" Symbol) option(Expression) 6390 6391 CancelExpression = "cancel" Expression; 6392 6393 ResumeExpression = "resume" Expression; 6394 6395 Defer(body) = ("defer" | "deferror") body 6396 6397 IfExpression(body) = "if" "(" Expression ")" body option("else" BlockExpression(body)) 6398 6399 SuspendExpression(body) = option(Symbol ":") "suspend" option(("|" Symbol "|" body)) 6400 6401 IfErrorExpression(body) = "if" "(" Expression ")" option("|" option("*") Symbol "|") body "else" "|" Symbol "|" BlockExpression(body) 6402 6403 TestExpression(body) = "if" "(" Expression ")" option("|" option("*") Symbol "|") body option("else" BlockExpression(body)) 6404 6405 WhileExpression(body) = option(Symbol ":") option("inline") "while" "(" Expression ")" option("|" option("*") Symbol "|") option(":" "(" Expression ")") body option("else" option("|" Symbol "|") BlockExpression(body)) 6406 6407 BoolAndExpression = ComparisonExpression "and" BoolAndExpression | ComparisonExpression 6408 6409 ComparisonExpression = BinaryOrExpression ComparisonOperator BinaryOrExpression | BinaryOrExpression 6410 6411 ComparisonOperator = "==" | "!=" | "<" | ">" | "<=" | ">=" 6412 6413 BinaryOrExpression = BinaryXorExpression "|" BinaryOrExpression | BinaryXorExpression 6414 6415 BinaryXorExpression = BinaryAndExpression "^" BinaryXorExpression | BinaryAndExpression 6416 6417 BinaryAndExpression = BitShiftExpression "&" BinaryAndExpression | BitShiftExpression 6418 6419 BitShiftExpression = AdditionExpression BitShiftOperator BitShiftExpression | AdditionExpression 6420 6421 BitShiftOperator = "<<" | ">>" 6422 6423 AdditionExpression = MultiplyExpression AdditionOperator AdditionExpression | MultiplyExpression 6424 6425 AdditionOperator = "+" | "-" | "++" | "+%" | "-%" 6426 6427 MultiplyExpression = CurlySuffixExpression MultiplyOperator MultiplyExpression | CurlySuffixExpression 6428 6429 CurlySuffixExpression = TypeExpr option(ContainerInitExpression) 6430 6431 MultiplyOperator = "||" | "*" | "/" | "%" | "**" | "*%" 6432 6433 PrefixOpExpression = PrefixOp TypeExpr | SuffixOpExpression 6434 6435 SuffixOpExpression = ("async" option("<" SuffixOpExpression ">") SuffixOpExpression FnCallExpression) | PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression | PtrDerefExpression) 6436 6437 FieldAccessExpression = "." Symbol 6438 6439 PtrDerefExpression = ".*" 6440 6441 FnCallExpression = "(" list(Expression, ",") ")" 6442 6443 ArrayAccessExpression = "[" Expression "]" 6444 6445 SliceExpression = "[" Expression ".." option(Expression) "]" 6446 6447 ContainerInitExpression = "{" ContainerInitBody "}" 6448 6449 ContainerInitBody = list(StructLiteralField, ",") | list(Expression, ",") 6450 6451 StructLiteralField = "." Symbol "=" Expression 6452 6453 PrefixOp = "!" | "-" | "~" | ("*" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "??" | "-%" | "try" | "await" 6454 6455 PrimaryExpression = Integer | Float | String | CharLiteral | KeywordLiteral | GroupedExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | FnProto | AsmExpression | ContainerDecl | ("continue" option(":" Symbol)) | ErrorSetDecl | PromiseType 6456 6457 PromiseType = "promise" option("->" TypeExpr) 6458 6459 ArrayType : "[" option(Expression) "]" option("align" "(" Expression option(":" Integer ":" Integer) ")")) option("const") option("volatile") TypeExpr 6460 6461 GroupedExpression = "(" Expression ")" 6462 6463 KeywordLiteral = "true" | "false" | "null" | "undefined" | "error" | "this" | "unreachable" | "suspend" 6464 6465 ErrorSetDecl = "error" "{" list(Symbol, ",") "}" 6466 6467 ContainerDecl = option("extern" | "packed") 6468 ("struct" option(GroupedExpression) | "union" option("enum" option(GroupedExpression) | GroupedExpression) | ("enum" option(GroupedExpression))) 6469 "{" many(ContainerMember) "}"</code></pre> 6470 {#header_close#} 6471 {#header_open|Zen#} 6472 <ul> 6473 <li>Communicate intent precisely.</li> 6474 <li>Edge cases matter.</li> 6475 <li>Favor reading code over writing code.</li> 6476 <li>Only one obvious way to do things.</li> 6477 <li>Runtime crashes are better than bugs.</li> 6478 <li>Compile errors are better than runtime crashes.</li> 6479 <li>Incremental improvements.</li> 6480 <li>Avoid local maximums.</li> 6481 <li>Reduce the amount one must remember.</li> 6482 <li>Minimize energy spent on coding style.</li> 6483 <li>Together we serve end users.</li> 6484 </ul> 6485 {#header_close#} 6486 </div> 6487 <script> 6488 /*! highlight.js v9.12.0 | BSD3 License | git.io/hljslicense */ 6489 !function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0===t.index}function a(e){return k.test(e)}function i(e){var n,t,r,i,o=e.className+" ";if(o+=e.parentNode?e.parentNode.className:"",t=B.exec(o))return w(t[1])?t[1]:"no-highlight";for(o=o.split(/\s+/),n=0,r=o.length;r>n;n++)if(i=o[n],a(i)||w(i))return i}function o(e){var n,t={},r=Array.prototype.slice.call(arguments,1);for(n in e)t[n]=e[n];return r.forEach(function(e){for(n in e)t[n]=e[n]}),t}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3===i.nodeType?a+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!==r[0].offset?e[0].offset<r[0].offset?e:r:"start"===r[0].event?e:r:e.length?e:r}function o(e){function r(e){return" "+e.nodeName+'="'+n(e.value).replace('"',""")+'"'}s+="<"+t(e)+E.map.call(e.attributes,r).join("")+">"}function u(e){s+="</"+t(e)+">"}function c(e){("start"===e.event?o:u)(e.node)}for(var l=0,s="",f=[];e.length||r.length;){var g=i();if(s+=n(a.substring(l,g[0].offset)),l=g[0].offset,g===e){f.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g===e&&g.length&&g[0].offset===l);f.reverse().forEach(o)}else"start"===g[0].event?f.push(g[0].node):f.pop(),c(g.splice(0,1)[0])}return s+n(a.substr(l))}function l(e){return e.v&&!e.cached_variants&&(e.cached_variants=e.v.map(function(n){return o(e,{v:null},n)})),e.cached_variants||e.eW&&[o(e)]||[e]}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var o={},u=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");o[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?u("keyword",a.k):x(a.k).forEach(function(e){u(e,a.k[e])}),a.k=o}a.lR=t(a.l||/\w+/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),null==a.r&&(a.r=1),a.c||(a.c=[]),a.c=Array.prototype.concat.apply([],a.c.map(function(e){return l("self"===e?a:e)})),a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var c=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=c.length?t(c.join("|"),!0):{exec:function(){return null}}}}r(e)}function f(e,t,a,i){function o(e,n){var t,a;for(t=0,a=n.c.length;a>t;t++)if(r(n.c[t].bR,e))return n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function c(e,n){return!a&&r(n.iR,e)}function l(e,n){var t=N.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function p(e,n,t,r){var a=r?"":I.classPrefix,i='<span class="'+a,o=t?"":C;return i+=e+'">',i+n+o}function h(){var e,t,r,a;if(!E.k)return n(k);for(a="",t=0,E.lR.lastIndex=0,r=E.lR.exec(k);r;)a+=n(k.substring(t,r.index)),e=l(E,r),e?(B+=e[1],a+=p(e[0],n(r[0]))):a+=n(r[0]),t=E.lR.lastIndex,r=E.lR.exec(k);return a+n(k.substr(t))}function d(){var e="string"==typeof E.sL;if(e&&!y[E.sL])return n(k);var t=e?f(E.sL,k,!0,x[E.sL]):g(k,E.sL.length?E.sL:void 0);return E.r>0&&(B+=t.r),e&&(x[E.sL]=t.top),p(t.language,t.value,!1,!0)}function b(){L+=null!=E.sL?d():h(),k=""}function v(e){L+=e.cN?p(e.cN,"",!0):"",E=Object.create(e,{parent:{value:E}})}function m(e,n){if(k+=e,null==n)return b(),0;var t=o(n,E);if(t)return t.skip?k+=n:(t.eB&&(k+=n),b(),t.rB||t.eB||(k=n)),v(t,n),t.rB?0:n.length;var r=u(E,n);if(r){var a=E;a.skip?k+=n:(a.rE||a.eE||(k+=n),b(),a.eE&&(k=n));do E.cN&&(L+=C),E.skip||(B+=E.r),E=E.parent;while(E!==r.parent);return r.starts&&v(r.starts,""),a.rE?0:n.length}if(c(n,E))throw new Error('Illegal lexeme "'+n+'" for mode "'+(E.cN||"<unnamed>")+'"');return k+=n,n.length||1}var N=w(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var R,E=i||N,x={},L="";for(R=E;R!==N;R=R.parent)R.cN&&(L=p(R.cN,"",!0)+L);var k="",B=0;try{for(var M,j,O=0;;){if(E.t.lastIndex=O,M=E.t.exec(t),!M)break;j=m(t.substring(O,M.index),M[0]),O=M.index+j}for(m(t.substr(O)),R=E;R.parent;R=R.parent)R.cN&&(L+=C);return{r:B,value:L,language:e,top:E}}catch(T){if(T.message&&-1!==T.message.indexOf("Illegal"))return{r:0,value:n(t)};throw T}}function g(e,t){t=t||I.languages||x(y);var r={r:0,value:n(e)},a=r;return t.filter(w).forEach(function(n){var t=f(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}),a.language&&(r.second_best=a),r}function p(e){return I.tabReplace||I.useBR?e.replace(M,function(e,n){return I.useBR&&"\n"===e?"<br>":I.tabReplace?n.replace(/\t/g,I.tabReplace):""}):e}function h(e,n,t){var r=n?L[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function d(e){var n,t,r,o,l,s=i(e);a(s)||(I.useBR?(n=document.createElementNS("http://www.w3.org/1999/xhtml","div"),n.innerHTML=e.innerHTML.replace(/\n/g,"").replace(/<br[ \/]*>/g,"\n")):n=e,l=n.textContent,r=s?f(s,l,!0):g(l),t=u(n),t.length&&(o=document.createElementNS("http://www.w3.org/1999/xhtml","div"),o.innerHTML=r.value,r.value=c(t,u(o),l)),r.value=p(r.value),e.innerHTML=r.value,e.className=h(e.className,s,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function b(e){I=o(I,e)}function v(){if(!v.called){v.called=!0;var e=document.querySelectorAll("pre code");E.forEach.call(e,d)}}function m(){addEventListener("DOMContentLoaded",v,!1),addEventListener("load",v,!1)}function N(n,t){var r=y[n]=t(e);r.aliases&&r.aliases.forEach(function(e){L[e]=n})}function R(){return x(y)}function w(e){return e=(e||"").toLowerCase(),y[e]||y[L[e]]}var E=[],x=Object.keys,y={},L={},k=/^(no-?highlight|plain|text)$/i,B=/\blang(?:uage)?-([\w-]+)\b/i,M=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,C="</span>",I={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0};return e.highlight=f,e.highlightAuto=g,e.fixMarkup=p,e.highlightBlock=d,e.configure=b,e.initHighlighting=v,e.initHighlightingOnLoad=m,e.registerLanguage=N,e.listLanguages=R,e.getLanguage=w,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e});hljs.registerLanguage("cpp",function(t){var e={cN:"keyword",b:"\\b[a-z\\d_]*_t\\b"},r={cN:"string",v:[{b:'(u8?|U)?L?"',e:'"',i:"\\n",c:[t.BE]},{b:'(u8?|U)?R"',e:'"',c:[t.BE]},{b:"'\\\\?.",e:"'",i:"."}]},s={cN:"number",v:[{b:"\\b(0b[01']+)"},{b:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{b:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],r:0},i={cN:"meta",b:/#\s*[a-z]+\b/,e:/$/,k:{"meta-keyword":"if else elif endif define undef warning error line pragma ifdef ifndef include"},c:[{b:/\\\n/,r:0},t.inherit(r,{cN:"meta-string"}),{cN:"meta-string",b:/<[^\n>]*>/,e:/$/,i:"\\n"},t.CLCM,t.CBCM]},a=t.IR+"\\s*\\(",c={keyword:"int float while private char catch import module export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignof constexpr decltype noexcept static_assert thread_local restrict _Bool complex _Complex _Imaginary atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong new throw return and or not",built_in:"std string cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr",literal:"true false nullptr NULL"},n=[e,t.CLCM,t.CBCM,s,r];return{aliases:["c","cc","h","c++","h++","hpp"],k:c,i:"</",c:n.concat([i,{b:"\\b(deque|list|queue|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<",e:">",k:c,c:["self",e]},{b:t.IR+"::",k:c},{v:[{b:/=/,e:/;/},{b:/\(/,e:/\)/},{bK:"new throw return else",e:/;/}],k:c,c:n.concat([{b:/\(/,e:/\)/,k:c,c:n.concat(["self"]),r:0}]),r:0},{cN:"function",b:"("+t.IR+"[\\*&\\s]+)+"+a,rB:!0,e:/[{;=]/,eE:!0,k:c,i:/[^\w\s\*&]/,c:[{b:a,rB:!0,c:[t.TM],r:0},{cN:"params",b:/\(/,e:/\)/,k:c,r:0,c:[t.CLCM,t.CBCM,r,s,e]},t.CLCM,t.CBCM,i]},{cN:"class",bK:"class struct",e:/[{;:]/,c:[{b:/</,e:/>/,c:["self"]},t.TM]}]),exports:{preprocessor:i,strings:r,k:c}}});hljs.registerLanguage("llvm",function(e){var n="([-a-zA-Z$._][\\w\\-$.]*)";return{k:"begin end true false declare define global constant private linker_private internal available_externally linkonce linkonce_odr weak weak_odr appending dllimport dllexport common default hidden protected extern_weak external thread_local zeroinitializer undef null to tail target triple datalayout volatile nuw nsw nnan ninf nsz arcp fast exact inbounds align addrspace section alias module asm sideeffect gc dbg linker_private_weak attributes blockaddress initialexec localdynamic localexec prefix unnamed_addr ccc fastcc coldcc x86_stdcallcc x86_fastcallcc arm_apcscc arm_aapcscc arm_aapcs_vfpcc ptx_device ptx_kernel intel_ocl_bicc msp430_intrcc spir_func spir_kernel x86_64_sysvcc x86_64_win64cc x86_thiscallcc cc c signext zeroext inreg sret nounwind noreturn noalias nocapture byval nest readnone readonly inlinehint noinline alwaysinline optsize ssp sspreq noredzone noimplicitfloat naked builtin cold nobuiltin noduplicate nonlazybind optnone returns_twice sanitize_address sanitize_memory sanitize_thread sspstrong uwtable returned type opaque eq ne slt sgt sle sge ult ugt ule uge oeq one olt ogt ole oge ord uno ueq une x acq_rel acquire alignstack atomic catch cleanup filter inteldialect max min monotonic nand personality release seq_cst singlethread umax umin unordered xchg add fadd sub fsub mul fmul udiv sdiv fdiv urem srem frem shl lshr ashr and or xor icmp fcmp phi call trunc zext sext fptrunc fpext uitofp sitofp fptoui fptosi inttoptr ptrtoint bitcast addrspacecast select va_arg ret br switch invoke unwind unreachable indirectbr landingpad resume malloc alloca free load store getelementptr extractelement insertelement shufflevector getresult extractvalue insertvalue atomicrmw cmpxchg fence argmemonly double",c:[{cN:"keyword",b:"i\\d+"},e.C(";","\\n",{r:0}),e.QSM,{cN:"string",v:[{b:'"',e:'[^\\\\]"'}],r:0},{cN:"title",v:[{b:"@"+n},{b:"@\\d+"},{b:"!"+n},{b:"!\\d+"+n}]},{cN:"symbol",v:[{b:"%"+n},{b:"%\\d+"},{b:"#\\d+"}]},{cN:"number",v:[{b:"0[xX][a-fA-F0-9]+"},{b:"-?\\d+(?:[.]\\d+)?(?:[eE][-+]?\\d+(?:[.]\\d+)?)?"}],r:0}]}});hljs.registerLanguage("bash",function(e){var t={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)}/}]},s={cN:"string",b:/"/,e:/"/,c:[e.BE,t,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]},a={cN:"string",b:/'/,e:/'/};return{aliases:["sh","zsh"],l:/\b-?[a-z\._]+\b/,k:{keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",_:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"meta",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:!0,c:[e.inherit(e.TM,{b:/\w[\w\d_]*/})],r:0},e.HCM,s,a,t]}});hljs.registerLanguage("shell",function(s){return{aliases:["console"],c:[{cN:"meta",b:"^\\s{0,3}[\\w\\d\\[\\]()@-]*[>%$#]",starts:{e:"$",sL:"bash"}}]}}); 6490 </script> 6491 <script> 6492 hljs.registerLanguage("zig", function(t) { 6493 var e = { 6494 cN: "keyword", 6495 b: "\\b[a-z\\d_]*_t\\b" 6496 }, 6497 r = { 6498 cN: "string", 6499 v: [{ 6500 b: '(u8?|U)?L?"', 6501 e: '"', 6502 i: "\\n", 6503 c: [t.BE] 6504 }, { 6505 b: '(u8?|U)?R"', 6506 e: '"', 6507 c: [t.BE] 6508 }, { 6509 b: "'\\\\?.", 6510 e: "'", 6511 i: "." 6512 }] 6513 }, 6514 s = { 6515 cN: "number", 6516 v: [{ 6517 b: "\\b(0b[01']+)" 6518 }, { 6519 b: "(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)" 6520 }, { 6521 b: "(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)" 6522 }], 6523 r: 0 6524 }, 6525 i = { 6526 cN: "meta", 6527 b: /#\s*[a-z]+\b/, 6528 e: /$/, 6529 k: { 6530 "meta-keyword": "zzzzzzdisable" 6531 }, 6532 c: [{ 6533 b: /\\\n/, 6534 r: 0 6535 }, t.inherit(r, { 6536 cN: "meta-string" 6537 }), { 6538 cN: "meta-string", 6539 b: /<[^\n>]*>/, 6540 e: /$/, 6541 i: "\\n" 6542 }, t.CLCM, t.CBCM] 6543 }, 6544 a = t.IR + "\\s*\\(", 6545 c = { 6546 keyword: "const align var extern stdcallcc nakedcc volatile export pub noalias inline struct packed enum union break return try catch test continue unreachable comptime and or asm defer errdefer if else switch while for fn use bool f32 f64 void type noreturn error i8 u8 i16 u16 i32 u32 i64 u64 isize usize i8w u8w i16w i32w u32w i64w u64w isizew usizew c_short c_ushort c_int c_uint c_long c_ulong c_longlong c_ulonglong", 6547 built_in: "atomicLoad breakpoint returnAddress frameAddress fieldParentPtr setFloatMode IntType OpaqueType compileError compileLog setCold setRuntimeSafety setEvalBranchQuota offsetOf memcpy inlineCall setGlobalLinkage setGlobalSection divTrunc divFloor enumTagName intToPtr ptrToInt panic canImplicitCast ptrCast bitCast rem mod memset sizeOf alignOf alignCast maxValue minValue memberCount memberName memberType typeOf addWithOverflow subWithOverflow mulWithOverflow shlWithOverflow shlExact shrExact cInclude cDefine cUndef ctz clz import cImport errorName embedFile cmpxchgStrong cmpxchgWeak fence divExact truncate atomicRmw sqrt field typeInfo newStackCall", 6548 literal: "true false null undefined" 6549 }, 6550 n = [e, t.CLCM, t.CBCM, s, r]; 6551 return { 6552 aliases: ["c", "cc", "h", "c++", "h++", "hpp"], 6553 k: c, 6554 i: "</", 6555 c: n.concat([i, { 6556 b: "\\b(deque|list|queue|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<", 6557 e: ">", 6558 k: c, 6559 c: ["self", e] 6560 }, { 6561 b: t.IR + "::", 6562 k: c 6563 }, { 6564 v: [{ 6565 b: /=/, 6566 e: /;/ 6567 }, { 6568 b: /\(/, 6569 e: /\)/ 6570 }, { 6571 bK: "new throw return else", 6572 e: /;/ 6573 }], 6574 k: c, 6575 c: n.concat([{ 6576 b: /\(/, 6577 e: /\)/, 6578 k: c, 6579 c: n.concat(["self"]), 6580 r: 0 6581 }]), 6582 r: 0 6583 }, { 6584 cN: "function", 6585 b: "(" + t.IR + "[\\*&\\s]+)+" + a, 6586 rB: !0, 6587 e: /[{;=]/, 6588 eE: !0, 6589 k: c, 6590 i: /[^\w\s\*&]/, 6591 c: [{ 6592 b: a, 6593 rB: !0, 6594 c: [t.TM], 6595 r: 0 6596 }, { 6597 cN: "params", 6598 b: /\(/, 6599 e: /\)/, 6600 k: c, 6601 r: 0, 6602 c: [t.CLCM, t.CBCM, r, s, e] 6603 }, t.CLCM, t.CBCM, i] 6604 }, { 6605 cN: "class", 6606 bK: "class struct", 6607 e: /[{;:]/, 6608 c: [{ 6609 b: /</, 6610 e: />/, 6611 c: ["self"] 6612 }, t.TM] 6613 }]), 6614 exports: { 6615 preprocessor: i, 6616 strings: r, 6617 k: c 6618 } 6619 } 6620 }); 6621 hljs.initHighlightingOnLoad(); 6622 </script> 6623 </body> 6624 </html>