| ... | ... | @@ -1694,7 +1694,7 @@ test "comptime @intToPtr" { |
| 1694 | 1694 | } |
| 1695 | 1695 | } |
| 1696 | 1696 | {#code_end#} |
| 1697 | | {#see_also|Optional Pointers#} |
| 1697 | {#see_also|Optional Pointers|@intToPtr|@ptrToInt#} |
| 1698 | 1698 | {#header_open|volatile#} |
| 1699 | 1699 | <p>Loads and stores are assumed to not have side effects. If a given load or store |
| 1700 | 1700 | should have side effects, such as Memory Mapped Input/Output (MMIO), use {#syntax#}volatile{#endsyntax#}. |
| ... | ... | @@ -1823,7 +1823,9 @@ fn foo(bytes: []u8) u32 { |
| 1823 | 1823 | } |
| 1824 | 1824 | {#code_end#} |
| 1825 | 1825 | {#header_close#} |
| 1826 | {#see_also|C Pointers#} |
| 1826 | 1827 | {#header_close#} |
| 1828 | |
| 1827 | 1829 | {#header_open|Slices#} |
| 1828 | 1830 | {#code_begin|test_safety|index out of bounds#} |
| 1829 | 1831 | const assert = @import("std").debug.assert; |
| ... | ... | @@ -3981,7 +3983,7 @@ test "implicit cast - invoke a type as a function" { |
| 3981 | 3983 | {#code_end#} |
| 3982 | 3984 | <p> |
| 3983 | 3985 | Implicit casts are only allowed when it is completely unambiguous how to get from one type to another, |
| 3984 | | and the transformation is guaranteed to be safe. |
| 3986 | and the transformation is guaranteed to be safe. There is one exception, which is {#link|C Pointers#}. |
| 3985 | 3987 | </p> |
| 3986 | 3988 | {#header_open|Implicit Cast: Stricter Qualification#} |
| 3987 | 3989 | <p> |
| ... | ... | @@ -6104,6 +6106,10 @@ test "call foo" { |
| 6104 | 6106 | <p> |
| 6105 | 6107 | Converts a pointer of one type to a pointer of another type. |
| 6106 | 6108 | </p> |
| 6109 | <p> |
| 6110 | {#link|Optional Pointers#} are allowed. Casting an optional pointer which is {#link|null#} |
| 6111 | to a non-optional pointer invokes safety-checked {#link|Undefined Behavior#}. |
| 6112 | </p> |
| 6107 | 6113 | {#header_close#} |
| 6108 | 6114 | |
| 6109 | 6115 | {#header_open|@ptrToInt#} |
| ... | ... | @@ -7345,10 +7351,27 @@ fn bar(f: *Foo) void { |
| 7345 | 7351 | {#code_end#} |
| 7346 | 7352 | {#header_close#} |
| 7347 | 7353 | |
| 7348 | | {#header_open|Out of Bounds Float To Integer Cast#} |
| 7354 | {#header_open|Out of Bounds Float to Integer Cast#} |
| 7349 | 7355 | <p>TODO</p> |
| 7350 | 7356 | {#header_close#} |
| 7351 | 7357 | |
| 7358 | {#header_open|Pointer Cast Invalid Null#} |
| 7359 | <p>At compile-time:</p> |
| 7360 | {#code_begin|test_err|null pointer casted to type#} |
| 7361 | comptime { |
| 7362 | const opt_ptr: ?*i32 = null; |
| 7363 | const ptr = @ptrCast(*i32, opt_ptr); |
| 7364 | } |
| 7365 | {#code_end#} |
| 7366 | <p>At runtime:</p> |
| 7367 | {#code_begin|exe_err#} |
| 7368 | pub fn main() void { |
| 7369 | var opt_ptr: ?*i32 = null; |
| 7370 | var ptr = @ptrCast(*i32, opt_ptr); |
| 7371 | } |
| 7372 | {#code_end#} |
| 7373 | {#header_close#} |
| 7374 | |
| 7352 | 7375 | {#header_close#} |
| 7353 | 7376 | {#header_open|Memory#} |
| 7354 | 7377 | <p>TODO: explain no default allocator in zig</p> |
| ... | ... | @@ -7439,6 +7462,7 @@ pub fn main() void { |
| 7439 | 7462 | {#code_end#} |
| 7440 | 7463 | {#see_also|String Literals#} |
| 7441 | 7464 | {#header_close#} |
| 7465 | |
| 7442 | 7466 | {#header_open|Import from C Header File#} |
| 7443 | 7467 | <p> |
| 7444 | 7468 | The {#syntax#}@cImport{#endsyntax#} builtin function can be used |
| ... | ... | @@ -7477,6 +7501,36 @@ const c = @cImport({ |
| 7477 | 7501 | {#code_end#} |
| 7478 | 7502 | {#see_also|@cImport|@cInclude|@cDefine|@cUndef|@import#} |
| 7479 | 7503 | {#header_close#} |
| 7504 | |
| 7505 | {#header_open|C Pointers#} |
| 7506 | <p> |
| 7507 | This type is to be avoided whenever possible. The only valid reason for using a C pointer is in |
| 7508 | auto-generated code from translating C code. |
| 7509 | </p> |
| 7510 | <p> |
| 7511 | When importing C header files, it is ambiguous whether pointers should be translated as |
| 7512 | single-item pointers ({#syntax#}*T{#endsyntax#}) or unknown-length pointers ({#syntax#}[*]T{#endsyntax#}). |
| 7513 | C pointers are a compromise so that Zig code can utilize translated header files directly. |
| 7514 | </p> |
| 7515 | <p>{#syntax#}[*c]T{#endsyntax#} - C pointer.</p> |
| 7516 | <ul> |
| 7517 | <li>Supports all the syntax of the other two pointer types.</li> |
| 7518 | <li>Implicitly casts to other pointer types, as well as {#link|Optional Pointers#}. |
| 7519 | When a C pointer is implicitly casted to a non-optional pointer, safety-checked |
| 7520 | {#link|Undefined Behavior#} occurs if the address is 0. |
| 7521 | </li> |
| 7522 | <li>Allows address 0. On non-freestanding targets, dereferencing address 0 is safety-checked |
| 7523 | {#link|Undefined Behavior#}. Optional C pointers introduce another bit to keep track of |
| 7524 | null, just like {#syntax#}?usize{#endsyntax#}. Note that creating an optional C pointer |
| 7525 | is unnecessary as one can use normal {#link|Optional Pointers#}. |
| 7526 | </li> |
| 7527 | <li>Supports {#link|implicit casting|Implicit Casts#} to and from integers.</li> |
| 7528 | <li>Supports comparison with integers.</li> |
| 7529 | <li>Does not support Zig-only pointer attributes such as alignment. Use normal {#link|Pointers#} |
| 7530 | please!</li> |
| 7531 | </ul> |
| 7532 | {#header_close#} |
| 7533 | |
| 7480 | 7534 | {#header_open|Exporting a C Library#} |
| 7481 | 7535 | <p> |
| 7482 | 7536 | One of the primary use cases for Zig is exporting a library with the C ABI for other programming languages |