From 973a93d43b8b44d2ee8bfde09e78f8295470f337 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 14 Feb 2019 18:59:20 -0500 Subject: [PATCH] add docs for C pointers --- doc/langref.html.in | 60 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/doc/langref.html.in b/doc/langref.html.in index 82ec13c9bb..e5a60b0bc1 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -1694,7 +1694,7 @@ test "comptime @intToPtr" { } } {#code_end#} - {#see_also|Optional Pointers#} + {#see_also|Optional Pointers|@intToPtr|@ptrToInt#} {#header_open|volatile#}

Loads and stores are assumed to not have side effects. If a given load or store should have side effects, such as Memory Mapped Input/Output (MMIO), use {#syntax#}volatile{#endsyntax#}. @@ -1823,7 +1823,9 @@ fn foo(bytes: []u8) u32 { } {#code_end#} {#header_close#} + {#see_also|C Pointers#} {#header_close#} + {#header_open|Slices#} {#code_begin|test_safety|index out of bounds#} const assert = @import("std").debug.assert; @@ -3981,7 +3983,7 @@ test "implicit cast - invoke a type as a function" { {#code_end#}

Implicit casts are only allowed when it is completely unambiguous how to get from one type to another, - and the transformation is guaranteed to be safe. + and the transformation is guaranteed to be safe. There is one exception, which is {#link|C Pointers#}.

{#header_open|Implicit Cast: Stricter Qualification#}

@@ -6104,6 +6106,10 @@ test "call foo" {

Converts a pointer of one type to a pointer of another type.

+

+ {#link|Optional Pointers#} are allowed. Casting an optional pointer which is {#link|null#} + to a non-optional pointer invokes safety-checked {#link|Undefined Behavior#}. +

{#header_close#} {#header_open|@ptrToInt#} @@ -7345,10 +7351,27 @@ fn bar(f: *Foo) void { {#code_end#} {#header_close#} - {#header_open|Out of Bounds Float To Integer Cast#} + {#header_open|Out of Bounds Float to Integer Cast#}

TODO

{#header_close#} + {#header_open|Pointer Cast Invalid Null#} +

At compile-time:

+ {#code_begin|test_err|null pointer casted to type#} +comptime { + const opt_ptr: ?*i32 = null; + const ptr = @ptrCast(*i32, opt_ptr); +} + {#code_end#} +

At runtime:

+ {#code_begin|exe_err#} +pub fn main() void { + var opt_ptr: ?*i32 = null; + var ptr = @ptrCast(*i32, opt_ptr); +} + {#code_end#} + {#header_close#} + {#header_close#} {#header_open|Memory#}

TODO: explain no default allocator in zig

@@ -7439,6 +7462,7 @@ pub fn main() void { {#code_end#} {#see_also|String Literals#} {#header_close#} + {#header_open|Import from C Header File#}

The {#syntax#}@cImport{#endsyntax#} builtin function can be used @@ -7477,6 +7501,36 @@ const c = @cImport({ {#code_end#} {#see_also|@cImport|@cInclude|@cDefine|@cUndef|@import#} {#header_close#} + + {#header_open|C Pointers#} +

+ This type is to be avoided whenever possible. The only valid reason for using a C pointer is in + auto-generated code from translating C code. +

+

+ When importing C header files, it is ambiguous whether pointers should be translated as + single-item pointers ({#syntax#}*T{#endsyntax#}) or unknown-length pointers ({#syntax#}[*]T{#endsyntax#}). + C pointers are a compromise so that Zig code can utilize translated header files directly. +

+

{#syntax#}[*c]T{#endsyntax#} - C pointer.

+ + {#header_close#} + {#header_open|Exporting a C Library#}

One of the primary use cases for Zig is exporting a library with the C ABI for other programming languages