| ... | @@ -549,7 +549,8 @@ pub fn main() void { | ... | @@ -549,7 +549,8 @@ pub fn main() void { |
| 549 | String literals are single-item constant {#link|Pointers#} to null-terminated UTF-8 encoded byte arrays. | 549 | String literals are single-item constant {#link|Pointers#} to null-terminated UTF-8 encoded byte arrays. |
| 550 | The type of string literals encodes both the length, and the fact that they are null-terminated, | 550 | The type of string literals encodes both the length, and the fact that they are null-terminated, |
| 551 | and thus they can be {#link|coerced|Type Coercion#} to both {#link|Slices#} and | 551 | and thus they can be {#link|coerced|Type Coercion#} to both {#link|Slices#} and |
| 552 | {#link|Null-Terminated Pointers#}. Dereferencing string literals converts them to {#link|Arrays#}. | 552 | {#link|Null-Terminated Pointers|Sentinel-Terminated Pointers#}. |
| | 553 | Dereferencing string literals converts them to {#link|Arrays#}. |
| 553 | </p> | 554 | </p> |
| 554 | <p> | 555 | <p> |
| 555 | Character literals have type {#syntax#}comptime_int{#endsyntax#}, the same as | 556 | Character literals have type {#syntax#}comptime_int{#endsyntax#}, the same as |
| ... | @@ -1780,9 +1781,9 @@ test "multidimensional arrays" { | ... | @@ -1780,9 +1781,9 @@ test "multidimensional arrays" { |
| 1780 | {#code_end#} | 1781 | {#code_end#} |
| 1781 | {#header_close#} | 1782 | {#header_close#} |
| 1782 | | 1783 | |
| 1783 | {#header_open|Null-Terminated Arrays#} | 1784 | {#header_open|Sentinel-Terminated Arrays#} |
| 1784 | <p> | 1785 | <p> |
| 1785 | The syntax {#syntax#}[N]null T{#endsyntax#} describes an array which has a null element at the | 1786 | The syntax {#syntax#}[N:x]T{#endsyntax#} describes an array which has a sentinel element at the |
| 1786 | index corresponding to {#syntax#}len{#endsyntax#}. | 1787 | index corresponding to {#syntax#}len{#endsyntax#}. |
| 1787 | </p> | 1788 | </p> |
| 1788 | {#code_begin|test|null_terminated_array#} | 1789 | {#code_begin|test|null_terminated_array#} |
| ... | @@ -1790,14 +1791,14 @@ const std = @import("std"); | ... | @@ -1790,14 +1791,14 @@ const std = @import("std"); |
| 1790 | const assert = std.debug.assert; | 1791 | const assert = std.debug.assert; |
| 1791 | | 1792 | |
| 1792 | test "null terminated array" { | 1793 | test "null terminated array" { |
| 1793 | const array = [_]u8 null {1, 2, 3, 4}; | 1794 | const array = [_:0]u8 {1, 2, 3, 4}; |
| 1794 | | 1795 | |
| 1795 | assert(@typeOf(array) == [4]null u8); | 1796 | assert(@typeOf(array) == [4:0]u8); |
| 1796 | assert(array.len == 4); | 1797 | assert(array.len == 4); |
| 1797 | assert(slice[4] == 0); | 1798 | assert(slice[4] == 0); |
| 1798 | } | 1799 | } |
| 1799 | {#code_end#} | 1800 | {#code_end#} |
| 1800 | {#see_also|Null-Terminated Pointers|Null-Terminated Slices#} | 1801 | {#see_also|Sentinel-Terminated Pointers|Sentinel-Terminated Slices#} |
| 1801 | {#header_close#} | 1802 | {#header_close#} |
| 1802 | {#header_close#} | 1803 | {#header_close#} |
| 1803 | | 1804 | |
| ... | @@ -1899,7 +1900,7 @@ test "pointer array access" { | ... | @@ -1899,7 +1900,7 @@ test "pointer array access" { |
| 1899 | } | 1900 | } |
| 1900 | {#code_end#} | 1901 | {#code_end#} |
| 1901 | <p> | 1902 | <p> |
| 1902 | In Zig, we prefer slices over pointers to null-terminated arrays. | 1903 | In Zig, we generally prefer {#link|Slices#} rather than {#link|Sentinel-Terminated Pointers#}. |
| 1903 | You can turn an array or pointer into a slice using slice syntax. | 1904 | You can turn an array or pointer into a slice using slice syntax. |
| 1904 | </p> | 1905 | </p> |
| 1905 | <p> | 1906 | <p> |
| ... | @@ -2112,17 +2113,17 @@ test "allowzero" { | ... | @@ -2112,17 +2113,17 @@ test "allowzero" { |
| 2112 | {#code_end#} | 2113 | {#code_end#} |
| 2113 | {#header_close#} | 2114 | {#header_close#} |
| 2114 | | 2115 | |
| 2115 | {#header_open|Null-Terminated Pointers#} | 2116 | {#header_open|Sentinel-Terminated Pointers#} |
| 2116 | <p> | 2117 | <p> |
| 2117 | The syntax {#syntax#}[*]null T{#endsyntax#} describes a pointer that | 2118 | The syntax {#syntax#}[*:x]T{#endsyntax#} describes a pointer that |
| 2118 | has a length determined by a sentinel null value. This provides protection | 2119 | has a length determined by a sentinel value. This provides protection |
| 2119 | against buffer overflow and overreads. | 2120 | against buffer overflow and overreads. |
| 2120 | </p> | 2121 | </p> |
| 2121 | {#code_begin|exe_build_err#} | 2122 | {#code_begin|exe_build_err#} |
| 2122 | const std = @import("std"); | 2123 | const std = @import("std"); |
| 2123 | | 2124 | |
| 2124 | // This is also available as `std.c.printf`. | 2125 | // This is also available as `std.c.printf`. |
| 2125 | pub extern "c" fn printf(format: [*]null const u8, ...) c_int; | 2126 | pub extern "c" fn printf(format: [*:0]const u8, ...) c_int; |
| 2126 | | 2127 | |
| 2127 | pub fn main() anyerror!void { | 2128 | pub fn main() anyerror!void { |
| 2128 | _ = printf("Hello, world!\n"); // OK | 2129 | _ = printf("Hello, world!\n"); // OK |
| ... | @@ -2132,7 +2133,7 @@ pub fn main() anyerror!void { | ... | @@ -2132,7 +2133,7 @@ pub fn main() anyerror!void { |
| 2132 | _ = printf(&non_null_terminated_msg); | 2133 | _ = printf(&non_null_terminated_msg); |
| 2133 | } | 2134 | } |
| 2134 | {#code_end#} | 2135 | {#code_end#} |
| 2135 | {#see_also|Null-Terminated Slices|Null-Terminated Arrays#} | 2136 | {#see_also|Sentinel-Terminated Slices|Sentinel-Terminated Arrays#} |
| 2136 | {#header_close#} | 2137 | {#header_close#} |
| 2137 | {#header_close#} | 2138 | {#header_close#} |
| 2138 | | 2139 | |
| ... | @@ -2218,11 +2219,11 @@ test "slice widening" { | ... | @@ -2218,11 +2219,11 @@ test "slice widening" { |
| 2218 | {#code_end#} | 2219 | {#code_end#} |
| 2219 | {#see_also|Pointers|for|Arrays#} | 2220 | {#see_also|Pointers|for|Arrays#} |
| 2220 | | 2221 | |
| 2221 | {#header_open|Null-Terminated Slices#} | 2222 | {#header_open|Sentinel-Terminated Slices#} |
| 2222 | <p> | 2223 | <p> |
| 2223 | The syntax {#syntax#}[]null T{#endsyntax#} is a slice which has a runtime known length | 2224 | The syntax {#syntax#}[:x]T{#endsyntax#} is a slice which has a runtime known length |
| 2224 | and also guarantees a null value at the element indexed by the length. The type does not | 2225 | and also guarantees a sentinel value at the element indexed by the length. The type does not |
| 2225 | guarantee that there are no null elements before that. Null-terminated slices allow element | 2226 | guarantee that there are no sentinel elements before that. Sentinel-terminated slices allow element |
| 2226 | access to the {#syntax#}len{#endsyntax#} index. | 2227 | access to the {#syntax#}len{#endsyntax#} index. |
| 2227 | </p> | 2228 | </p> |
| 2228 | {#code_begin|test|null_terminated_slice#} | 2229 | {#code_begin|test|null_terminated_slice#} |
| ... | @@ -2230,13 +2231,13 @@ const std = @import("std"); | ... | @@ -2230,13 +2231,13 @@ const std = @import("std"); |
| 2230 | const assert = std.debug.assert; | 2231 | const assert = std.debug.assert; |
| 2231 | | 2232 | |
| 2232 | test "null terminated slice" { | 2233 | test "null terminated slice" { |
| 2233 | const slice: []null const u8 = "hello"; | 2234 | const slice: [:0]const u8 = "hello"; |
| 2234 | | 2235 | |
| 2235 | assert(slice.len == 5); | 2236 | assert(slice.len == 5); |
| 2236 | assert(slice[5] == 0); | 2237 | assert(slice[5] == 0); |
| 2237 | } | 2238 | } |
| 2238 | {#code_end#} | 2239 | {#code_end#} |
| 2239 | {#see_also|Null-Terminated Pointers|Null-Terminated Arrays#} | 2240 | {#see_also|Sentinel-Terminated Pointers|Sentinel-Terminated Arrays#} |
| 2240 | {#header_close#} | 2241 | {#header_close#} |
| 2241 | {#header_close#} | 2242 | {#header_close#} |
| 2242 | | 2243 | |