@@ -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
0 commit comments