| ... | @@ -1694,7 +1694,7 @@ test "comptime @intToPtr" { | ... | @@ -1694,7 +1694,7 @@ test "comptime @intToPtr" { |
| 1694 | } | 1694 | } |
| 1695 | } | 1695 | } |
| 1696 | {#code_end#} | 1696 | {#code_end#} |
| 1697 | {#see_also|Optional Pointers#} | 1697 | {#see_also|Optional Pointers|@intToPtr|@ptrToInt#} |
| 1698 | {#header_open|volatile#} | 1698 | {#header_open|volatile#} |
| 1699 | <p>Loads and stores are assumed to not have side effects. If a given load or store | 1699 | <p>Loads and stores are assumed to not have side effects. If a given load or store |
| 1700 | should have side effects, such as Memory Mapped Input/Output (MMIO), use {#syntax#}volatile{#endsyntax#}. | 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,7 +1823,9 @@ fn foo(bytes: []u8) u32 { |
| 1823 | } | 1823 | } |
| 1824 | {#code_end#} | 1824 | {#code_end#} |
| 1825 | {#header_close#} | 1825 | {#header_close#} |
| | 1826 | {#see_also|C Pointers#} |
| 1826 | {#header_close#} | 1827 | {#header_close#} |
| | 1828 | |
| 1827 | {#header_open|Slices#} | 1829 | {#header_open|Slices#} |
| 1828 | {#code_begin|test_safety|index out of bounds#} | 1830 | {#code_begin|test_safety|index out of bounds#} |
| 1829 | const assert = @import("std").debug.assert; | 1831 | const assert = @import("std").debug.assert; |
| ... | @@ -3981,7 +3983,7 @@ test "implicit cast - invoke a type as a function" { | ... | @@ -3981,7 +3983,7 @@ test "implicit cast - invoke a type as a function" { |
| 3981 | {#code_end#} | 3983 | {#code_end#} |
| 3982 | <p> | 3984 | <p> |
| 3983 | Implicit casts are only allowed when it is completely unambiguous how to get from one type to another, | 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 | </p> | 3987 | </p> |
| 3986 | {#header_open|Implicit Cast: Stricter Qualification#} | 3988 | {#header_open|Implicit Cast: Stricter Qualification#} |
| 3987 | <p> | 3989 | <p> |
| ... | @@ -6104,6 +6106,10 @@ test "call foo" { | ... | @@ -6104,6 +6106,10 @@ test "call foo" { |
| 6104 | <p> | 6106 | <p> |
| 6105 | Converts a pointer of one type to a pointer of another type. | 6107 | Converts a pointer of one type to a pointer of another type. |
| 6106 | </p> | 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 | {#header_close#} | 6113 | {#header_close#} |
| 6108 | | 6114 | |
| 6109 | {#header_open|@ptrToInt#} | 6115 | {#header_open|@ptrToInt#} |
| ... | @@ -7345,10 +7351,27 @@ fn bar(f: *Foo) void { | ... | @@ -7345,10 +7351,27 @@ fn bar(f: *Foo) void { |
| 7345 | {#code_end#} | 7351 | {#code_end#} |
| 7346 | {#header_close#} | 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 | <p>TODO</p> | 7355 | <p>TODO</p> |
| 7350 | {#header_close#} | 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 | {#header_close#} | 7375 | {#header_close#} |
| 7353 | {#header_open|Memory#} | 7376 | {#header_open|Memory#} |
| 7354 | <p>TODO: explain no default allocator in zig</p> | 7377 | <p>TODO: explain no default allocator in zig</p> |
| ... | @@ -7439,6 +7462,7 @@ pub fn main() void { | ... | @@ -7439,6 +7462,7 @@ pub fn main() void { |
| 7439 | {#code_end#} | 7462 | {#code_end#} |
| 7440 | {#see_also|String Literals#} | 7463 | {#see_also|String Literals#} |
| 7441 | {#header_close#} | 7464 | {#header_close#} |
| | 7465 | |
| 7442 | {#header_open|Import from C Header File#} | 7466 | {#header_open|Import from C Header File#} |
| 7443 | <p> | 7467 | <p> |
| 7444 | The {#syntax#}@cImport{#endsyntax#} builtin function can be used | 7468 | The {#syntax#}@cImport{#endsyntax#} builtin function can be used |
| ... | @@ -7477,6 +7501,36 @@ const c = @cImport({ | ... | @@ -7477,6 +7501,36 @@ const c = @cImport({ |
| 7477 | {#code_end#} | 7501 | {#code_end#} |
| 7478 | {#see_also|@cImport|@cInclude|@cDefine|@cUndef|@import#} | 7502 | {#see_also|@cImport|@cInclude|@cDefine|@cUndef|@import#} |
| 7479 | {#header_close#} | 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 | {#header_open|Exporting a C Library#} | 7534 | {#header_open|Exporting a C Library#} |
| 7481 | <p> | 7535 | <p> |
| 7482 | One of the primary use cases for Zig is exporting a library with the C ABI for other programming languages | 7536 | One of the primary use cases for Zig is exporting a library with the C ABI for other programming languages |