authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-02-22 18:41:35-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2025-02-22 18:41:35-05:00
log813312f0e871d436581c5d0be8700ee04aa2fb97
tree040e0fc53bfc7dd5b3fb3f5e2646c2ddc7e24781
parentb25d93e7d95418ea92b388ff8b58a04673c04539
parentcc64295a6313f8697ed02143390caa8fe3a63626
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #22714 from mlugg/langref

langref improvements

9 files changed, 319 insertions(+), 66 deletions(-)

doc/langref.html.in+221-59
...@@ -381,7 +381,7 @@...@@ -381,7 +381,7 @@
381 In this case, the {#syntax#}!{#endsyntax#} may be omitted from the return381 In this case, the {#syntax#}!{#endsyntax#} may be omitted from the return
382 type of <code>main</code> because no errors are returned from the function.382 type of <code>main</code> because no errors are returned from the function.
383 </p>383 </p>
384 {#see_also|Values|Tuples|@import|Errors|Root Source File|Source Encoding|try#}384 {#see_also|Values|Tuples|@import|Errors|Entry Point|Source Encoding|try#}
385 {#header_close#}385 {#header_close#}
386 {#header_open|Comments#}386 {#header_open|Comments#}
387 <p>387 <p>
...@@ -823,7 +823,7 @@...@@ -823,7 +823,7 @@
823 <kbd>zig test</kbd> is a tool that creates and runs a test build. By default, it builds and runs an823 <kbd>zig test</kbd> is a tool that creates and runs a test build. By default, it builds and runs an
824 executable program using the <em>default test runner</em> provided by the {#link|Zig Standard Library#}824 executable program using the <em>default test runner</em> provided by the {#link|Zig Standard Library#}
825 as its main entry point. During the build, {#syntax#}test{#endsyntax#} declarations found while825 as its main entry point. During the build, {#syntax#}test{#endsyntax#} declarations found while
826 {#link|resolving|Root Source File#} the given Zig source file are included for the default test runner826 {#link|resolving|File and Declaration Discovery#} the given Zig source file are included for the default test runner
827 to run and report on.827 to run and report on.
828 </p>828 </p>
829 <aside>829 <aside>
...@@ -1049,12 +1049,12 @@...@@ -1049,12 +1049,12 @@
1049 {#header_close#}1049 {#header_close#}
1050 {#header_open|Runtime Integer Values#}1050 {#header_open|Runtime Integer Values#}
1051 <p>1051 <p>
1052 Integer literals have no size limitation, and if any undefined behavior occurs,1052 Integer literals have no size limitation, and if any Illegal Behavior occurs,
1053 the compiler catches it.1053 the compiler catches it.
1054 </p>1054 </p>
1055 <p>1055 <p>
1056 However, once an integer value is no longer known at compile-time, it must have a1056 However, once an integer value is no longer known at compile-time, it must have a
1057 known size, and is vulnerable to undefined behavior.1057 known size, and is vulnerable to safety-checked {#link|Illegal Behavior#}.
1058 </p>1058 </p>
1059 {#code|runtime_vs_comptime.zig#}1059 {#code|runtime_vs_comptime.zig#}
10601060
...@@ -1064,7 +1064,7 @@...@@ -1064,7 +1064,7 @@
1064 {#link|Division by Zero#}.1064 {#link|Division by Zero#}.
1065 </p>1065 </p>
1066 <p>1066 <p>
1067 Operators such as {#syntax#}+{#endsyntax#} and {#syntax#}-{#endsyntax#} cause undefined behavior on1067 Operators such as {#syntax#}+{#endsyntax#} and {#syntax#}-{#endsyntax#} cause {#link|Illegal Behavior#} on
1068 integer overflow. Alternative operators are provided for wrapping and saturating arithmetic on all targets.1068 integer overflow. Alternative operators are provided for wrapping and saturating arithmetic on all targets.
1069 {#syntax#}+%{#endsyntax#} and {#syntax#}-%{#endsyntax#} perform wrapping arithmetic1069 {#syntax#}+%{#endsyntax#} and {#syntax#}-%{#endsyntax#} perform wrapping arithmetic
1070 while {#syntax#}+|{#endsyntax#} and {#syntax#}-|{#endsyntax#} perform saturating arithmetic.1070 while {#syntax#}+|{#endsyntax#} and {#syntax#}-|{#endsyntax#} perform saturating arithmetic.
...@@ -2029,7 +2029,7 @@ or...@@ -2029,7 +2029,7 @@ or
2029 </p>2029 </p>
2030 <p>2030 <p>
2031 Slices have bounds checking and are therefore protected2031 Slices have bounds checking and are therefore protected
2032 against this kind of undefined behavior. This is one reason2032 against this kind of Illegal Behavior. This is one reason
2033 we prefer slices to pointers.2033 we prefer slices to pointers.
2034 </p>2034 </p>
2035 {#code|test_slice_bounds.zig#}2035 {#code|test_slice_bounds.zig#}
...@@ -2048,7 +2048,7 @@ or...@@ -2048,7 +2048,7 @@ or
20482048
2049 <p>2049 <p>
2050 {#link|@ptrCast#} converts a pointer's element type to another. This2050 {#link|@ptrCast#} converts a pointer's element type to another. This
2051 creates a new pointer that can cause undetectable illegal behavior2051 creates a new pointer that can cause undetectable Illegal Behavior
2052 depending on the loads and stores that pass through it. Generally, other2052 depending on the loads and stores that pass through it. Generally, other
2053 kinds of type conversions are preferable to2053 kinds of type conversions are preferable to
2054 {#syntax#}@ptrCast{#endsyntax#} if possible.2054 {#syntax#}@ptrCast{#endsyntax#} if possible.
...@@ -2164,7 +2164,7 @@ or...@@ -2164,7 +2164,7 @@ or
21642164
2165 <p>2165 <p>
2166 Sentinel-terminated slicing asserts that the element in the sentinel position of the backing data is2166 Sentinel-terminated slicing asserts that the element in the sentinel position of the backing data is
2167 actually the sentinel value. If this is not the case, safety-protected {#link|Undefined Behavior#} results.2167 actually the sentinel value. If this is not the case, safety-checked {#link|Illegal Behavior#} results.
2168 </p>2168 </p>
2169 {#code|test_sentinel_mismatch.zig#}2169 {#code|test_sentinel_mismatch.zig#}
21702170
...@@ -2425,7 +2425,7 @@ or...@@ -2425,7 +2425,7 @@ or
2425 or use an {#link|extern union#} or a {#link|packed union#} which have2425 or use an {#link|extern union#} or a {#link|packed union#} which have
2426 guaranteed in-memory layout.2426 guaranteed in-memory layout.
2427 {#link|Accessing the non-active field|Wrong Union Field Access#} is2427 {#link|Accessing the non-active field|Wrong Union Field Access#} is
2428 safety-checked {#link|Undefined Behavior#}:2428 safety-checked {#link|Illegal Behavior#}:
2429 </p>2429 </p>
2430 {#code|test_wrong_union_access.zig#}2430 {#code|test_wrong_union_access.zig#}
24312431
...@@ -3023,11 +3023,11 @@ or...@@ -3023,11 +3023,11 @@ or
3023 {#syntax#}const number = parseU64("1234", 10) catch unreachable;{#endsyntax#}3023 {#syntax#}const number = parseU64("1234", 10) catch unreachable;{#endsyntax#}
3024 <p>3024 <p>
3025 Here we know for sure that "1234" will parse successfully. So we put the3025 Here we know for sure that "1234" will parse successfully. So we put the
3026 {#syntax#}unreachable{#endsyntax#} value on the right hand side. {#syntax#}unreachable{#endsyntax#} generates3026 {#syntax#}unreachable{#endsyntax#} value on the right hand side.
3027 a panic in {#link|Debug#} and {#link|ReleaseSafe#} modes and undefined behavior in3027 {#syntax#}unreachable{#endsyntax#} invokes safety-checked {#link|Illegal Behavior#}, so
3028 {#link|ReleaseFast#} and {#link|ReleaseSmall#} modes. So, while we're debugging the3028 in {#link|Debug#} and {#link|ReleaseSafe#}, triggers a safety panic by default. So, while
3029 application, if there <em>was</em> a surprise error here, the application would crash3029 we're debugging the application, if there <em>was</em> a surprise error here, the application
3030 appropriately.3030 would crash appropriately.
3031 </p>3031 </p>
3032 <p>3032 <p>
3033 You may want to take a different action for every situation. For that, we combine3033 You may want to take a different action for every situation. For that, we combine
...@@ -4034,7 +4034,7 @@ fn performFn(start_value: i32) i32 {...@@ -4034,7 +4034,7 @@ fn performFn(start_value: i32) i32 {
4034 </p>4034 </p>
4035 <p>4035 <p>
4036 Luckily, we used an unsigned integer, and so when we tried to subtract 1 from 0, it triggered4036 Luckily, we used an unsigned integer, and so when we tried to subtract 1 from 0, it triggered
4037 undefined behavior, which is always a compile error if the compiler knows it happened.4037 {#link|Illegal Behavior#}, which is always a compile error if the compiler knows it happened.
4038 But what would have happened if we used a signed integer?4038 But what would have happened if we used a signed integer?
4039 </p>4039 </p>
4040 {#code|fibonacci_comptime_infinite_recursion.zig#}4040 {#code|fibonacci_comptime_infinite_recursion.zig#}
...@@ -4239,7 +4239,7 @@ pub fn print(self: *Writer, arg0: []const u8, arg1: i32) !void {...@@ -4239,7 +4239,7 @@ pub fn print(self: *Writer, arg0: []const u8, arg1: i32) !void {
4239 </p>4239 </p>
4240 <p>4240 <p>
4241 Failure to declare the full set of clobbers for a given inline assembly4241 Failure to declare the full set of clobbers for a given inline assembly
4242 expression is unchecked {#link|Undefined Behavior#}.4242 expression is unchecked {#link|Illegal Behavior#}.
4243 </p>4243 </p>
4244 {#header_close#}4244 {#header_close#}
42454245
...@@ -4805,7 +4805,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val...@@ -4805,7 +4805,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
4805 </p>4805 </p>
4806 <p>4806 <p>
4807 Attempting to convert an integer with no corresponding value in the enum invokes4807 Attempting to convert an integer with no corresponding value in the enum invokes
4808 safety-checked {#link|Undefined Behavior#}.4808 safety-checked {#link|Illegal Behavior#}.
4809 Note that a {#link|non-exhaustive enum|Non-exhaustive enum#} has corresponding values for all4809 Note that a {#link|non-exhaustive enum|Non-exhaustive enum#} has corresponding values for all
4810 integers in the enum's integer tag type: the {#syntax#}_{#endsyntax#} value represents all4810 integers in the enum's integer tag type: the {#syntax#}_{#endsyntax#} value represents all
4811 the remaining unnamed integers in the enum's tag type.4811 the remaining unnamed integers in the enum's tag type.
...@@ -4824,7 +4824,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val...@@ -4824,7 +4824,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
4824 </p>4824 </p>
4825 <p>4825 <p>
4826 Attempting to convert an integer that does not correspond to any error results in4826 Attempting to convert an integer that does not correspond to any error results in
4827 safety-protected {#link|Undefined Behavior#}.4827 safety-checked {#link|Illegal Behavior#}.
4828 </p>4828 </p>
4829 {#see_also|@intFromError#}4829 {#see_also|@intFromError#}
4830 {#header_close#}4830 {#header_close#}
...@@ -4856,7 +4856,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val...@@ -4856,7 +4856,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
4856 <p>4856 <p>
4857 Converts an error set or error union value from one error set to another error set. The return type is the4857 Converts an error set or error union value from one error set to another error set. The return type is the
4858 inferred result type. Attempting to convert an error which is not in the destination error4858 inferred result type. Attempting to convert an error which is not in the destination error
4859 set results in safety-protected {#link|Undefined Behavior#}.4859 set results in safety-checked {#link|Illegal Behavior#}.
4860 </p>4860 </p>
4861 {#header_close#}4861 {#header_close#}
48624862
...@@ -4907,7 +4907,12 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val...@@ -4907,7 +4907,12 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
4907 {#header_open|@fieldParentPtr#}4907 {#header_open|@fieldParentPtr#}
4908 <pre>{#syntax#}@fieldParentPtr(comptime field_name: []const u8, field_ptr: *T) anytype{#endsyntax#}</pre>4908 <pre>{#syntax#}@fieldParentPtr(comptime field_name: []const u8, field_ptr: *T) anytype{#endsyntax#}</pre>
4909 <p>4909 <p>
4910 Given a pointer to a field, returns the base pointer of a struct.4910 Given a pointer to a struct field, returns a pointer to the struct containing that field.
4911 The return type (and struct in question) is the inferred result type.
4912 </p>
4913 <p>
4914 If {#syntax#}field_ptr{#endsyntax#} does not point to the {#syntax#}field_name{#endsyntax#} field of an instance of
4915 the result type, and the result type has ill-defined layout, invokes unchecked {#link|Illegal Behavior#}.
4911 </p>4916 </p>
4912 {#header_close#}4917 {#header_close#}
49134918
...@@ -5024,7 +5029,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val...@@ -5024,7 +5029,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
5024 Converts an integer to another integer while keeping the same numerical value.5029 Converts an integer to another integer while keeping the same numerical value.
5025 The return type is the inferred result type.5030 The return type is the inferred result type.
5026 Attempting to convert a number which is out of range of the destination type results in5031 Attempting to convert a number which is out of range of the destination type results in
5027 safety-protected {#link|Undefined Behavior#}.5032 safety-checked {#link|Illegal Behavior#}.
5028 </p>5033 </p>
5029 {#code|test_intCast_builtin.zig#}5034 {#code|test_intCast_builtin.zig#}
50305035
...@@ -5085,7 +5090,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val...@@ -5085,7 +5090,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
5085 </p>5090 </p>
5086 <p>5091 <p>
5087 If the integer part of the floating point number cannot fit in the destination type,5092 If the integer part of the floating point number cannot fit in the destination type,
5088 it invokes safety-checked {#link|Undefined Behavior#}.5093 it invokes safety-checked {#link|Illegal Behavior#}.
5089 </p>5094 </p>
5090 {#see_also|@floatFromInt#}5095 {#see_also|@floatFromInt#}
5091 {#header_close#}5096 {#header_close#}
...@@ -5217,7 +5222,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val...@@ -5217,7 +5222,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
5217 <li>From library code, calling the programmer's panic function if they exposed one in the root source file.</li>5222 <li>From library code, calling the programmer's panic function if they exposed one in the root source file.</li>
5218 <li>When mixing C and Zig code, calling the canonical panic implementation across multiple .o files.</li>5223 <li>When mixing C and Zig code, calling the canonical panic implementation across multiple .o files.</li>
5219 </ul>5224 </ul>
5220 {#see_also|Root Source File#}5225 {#see_also|Panic Handler#}
5221 {#header_close#}5226 {#header_close#}
52225227
5223 {#header_open|@popCount#}5228 {#header_open|@popCount#}
...@@ -5245,7 +5250,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val...@@ -5245,7 +5250,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
5245 <p>5250 <p>
5246 The {#syntax#}ptr{#endsyntax#} argument may be any pointer type and determines the memory5251 The {#syntax#}ptr{#endsyntax#} argument may be any pointer type and determines the memory
5247 address to prefetch. This function does not dereference the pointer, it is perfectly legal5252 address to prefetch. This function does not dereference the pointer, it is perfectly legal
5248 to pass a pointer to invalid memory to this function and no illegal behavior will result.5253 to pass a pointer to invalid memory to this function and no Illegal Behavior will result.
5249 </p>5254 </p>
5250 <p>{#syntax#}PrefetchOptions{#endsyntax#} can be found with {#syntax#}@import("std").builtin.PrefetchOptions{#endsyntax#}.</p>5255 <p>{#syntax#}PrefetchOptions{#endsyntax#} can be found with {#syntax#}@import("std").builtin.PrefetchOptions{#endsyntax#}.</p>
5251 {#header_close#}5256 {#header_close#}
...@@ -5257,7 +5262,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val...@@ -5257,7 +5262,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
5257 </p>5262 </p>
5258 <p>5263 <p>
5259 {#link|Optional Pointers#} are allowed. Casting an optional pointer which is {#link|null#}5264 {#link|Optional Pointers#} are allowed. Casting an optional pointer which is {#link|null#}
5260 to a non-optional pointer invokes safety-checked {#link|Undefined Behavior#}.5265 to a non-optional pointer invokes safety-checked {#link|Illegal Behavior#}.
5261 </p>5266 </p>
5262 <p>5267 <p>
5263 {#syntax#}@ptrCast{#endsyntax#} cannot be used for:5268 {#syntax#}@ptrCast{#endsyntax#} cannot be used for:
...@@ -5281,7 +5286,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val...@@ -5281,7 +5286,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
5281 </p>5286 </p>
5282 <p>5287 <p>
5283 If the destination pointer type does not allow address zero and {#syntax#}address{#endsyntax#}5288 If the destination pointer type does not allow address zero and {#syntax#}address{#endsyntax#}
5284 is zero, this invokes safety-checked {#link|Undefined Behavior#}.5289 is zero, this invokes safety-checked {#link|Illegal Behavior#}.
5285 </p>5290 </p>
5286 {#header_close#}5291 {#header_close#}
52875292
...@@ -5356,8 +5361,8 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val...@@ -5356,8 +5361,8 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
5356 <li>5361 <li>
5357 {#syntax#}Optimized{#endsyntax#} - Floating point operations may do all of the following:5362 {#syntax#}Optimized{#endsyntax#} - Floating point operations may do all of the following:
5358 <ul>5363 <ul>
5359 <li>Assume the arguments and result are not NaN. Optimizations are required to retain defined behavior over NaNs, but the value of the result is undefined.</li>5364 <li>Assume the arguments and result are not NaN. Optimizations are required to retain legal behavior over NaNs, but the value of the result is undefined.</li>
5360 <li>Assume the arguments and result are not +/-Inf. Optimizations are required to retain defined behavior over +/-Inf, but the value of the result is undefined.</li>5365 <li>Assume the arguments and result are not +/-Inf. Optimizations are required to retain legal behavior over +/-Inf, but the value of the result is undefined.</li>
5361 <li>Treat the sign of a zero argument or result as insignificant.</li>5366 <li>Treat the sign of a zero argument or result as insignificant.</li>
5362 <li>Use the reciprocal of an argument rather than perform division.</li>5367 <li>Use the reciprocal of an argument rather than perform division.</li>
5363 <li>Perform floating-point contraction (e.g. fusing a multiply followed by an addition into a fused multiply-add).</li>5368 <li>Perform floating-point contraction (e.g. fusing a multiply followed by an addition into a fused multiply-add).</li>
...@@ -5396,7 +5401,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val...@@ -5396,7 +5401,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
5396 </p>5401 </p>
5397 <p>5402 <p>
5398 The type of {#syntax#}shift_amt{#endsyntax#} is an unsigned integer with {#syntax#}log2(@typeInfo(T).int.bits){#endsyntax#} bits.5403 The type of {#syntax#}shift_amt{#endsyntax#} is an unsigned integer with {#syntax#}log2(@typeInfo(T).int.bits){#endsyntax#} bits.
5399 This is because {#syntax#}shift_amt >= @typeInfo(T).int.bits{#endsyntax#} is undefined behavior.5404 This is because {#syntax#}shift_amt >= @typeInfo(T).int.bits{#endsyntax#} triggers safety-checked {#link|Illegal Behavior#}.
5400 </p>5405 </p>
5401 <p>5406 <p>
5402 {#syntax#}comptime_int{#endsyntax#} is modeled as an integer with an infinite number of bits,5407 {#syntax#}comptime_int{#endsyntax#} is modeled as an integer with an infinite number of bits,
...@@ -5413,7 +5418,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val...@@ -5413,7 +5418,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
5413 </p>5418 </p>
5414 <p>5419 <p>
5415 The type of {#syntax#}shift_amt{#endsyntax#} is an unsigned integer with {#syntax#}log2(@typeInfo(@TypeOf(a)).int.bits){#endsyntax#} bits.5420 The type of {#syntax#}shift_amt{#endsyntax#} is an unsigned integer with {#syntax#}log2(@typeInfo(@TypeOf(a)).int.bits){#endsyntax#} bits.
5416 This is because {#syntax#}shift_amt >= @typeInfo(@TypeOf(a)).int.bits{#endsyntax#} is undefined behavior.5421 This is because {#syntax#}shift_amt >= @typeInfo(@TypeOf(a)).int.bits{#endsyntax#} triggers safety-checked {#link|Illegal Behavior#}.
5417 </p>5422 </p>
5418 {#see_also|@shlExact|@shrExact#}5423 {#see_also|@shlExact|@shrExact#}
5419 {#header_close#}5424 {#header_close#}
...@@ -5426,7 +5431,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val...@@ -5426,7 +5431,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
5426 </p>5431 </p>
5427 <p>5432 <p>
5428 The type of {#syntax#}shift_amt{#endsyntax#} is an unsigned integer with {#syntax#}log2(@typeInfo(T).int.bits){#endsyntax#} bits.5433 The type of {#syntax#}shift_amt{#endsyntax#} is an unsigned integer with {#syntax#}log2(@typeInfo(T).int.bits){#endsyntax#} bits.
5429 This is because {#syntax#}shift_amt >= @typeInfo(T).int.bits{#endsyntax#} is undefined behavior.5434 This is because {#syntax#}shift_amt >= @typeInfo(T).int.bits{#endsyntax#} triggers safety-checked {#link|Illegal Behavior#}.
5430 </p>5435 </p>
5431 {#see_also|@shlExact|@shlWithOverflow#}5436 {#see_also|@shlExact|@shlWithOverflow#}
5432 {#header_close#}5437 {#header_close#}
...@@ -5701,7 +5706,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val...@@ -5701,7 +5706,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
5701 {#header_open|@tagName#}5706 {#header_open|@tagName#}
5702 <pre>{#syntax#}@tagName(value: anytype) [:0]const u8{#endsyntax#}</pre>5707 <pre>{#syntax#}@tagName(value: anytype) [:0]const u8{#endsyntax#}</pre>
5703 <p>5708 <p>
5704 Converts an enum value or union value to a string literal representing the name.</p><p>If the enum is non-exhaustive and the tag value does not map to a name, it invokes safety-checked {#link|Undefined Behavior#}.5709 Converts an enum value or union value to a string literal representing the name.</p><p>If the enum is non-exhaustive and the tag value does not map to a name, it invokes safety-checked {#link|Illegal Behavior#}.
5705 </p>5710 </p>
5706 {#header_close#}5711 {#header_close#}
57075712
...@@ -5938,7 +5943,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val...@@ -5938,7 +5943,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
5938 <li>Reproducible build</li>5943 <li>Reproducible build</li>
5939 </ul>5944 </ul>
5940 {#header_close#}5945 {#header_close#}
5941 {#see_also|Compile Variables|Zig Build System|Undefined Behavior#}5946 {#see_also|Compile Variables|Zig Build System|Illegal Behavior#}
5942 {#header_close#}5947 {#header_close#}
59435948
5944 {#header_open|Single Threaded Builds#}5949 {#header_open|Single Threaded Builds#}
...@@ -5953,20 +5958,36 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val...@@ -5953,20 +5958,36 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
5953 </ul>5958 </ul>
5954 {#header_close#}5959 {#header_close#}
59555960
5956 {#header_open|Undefined Behavior#}5961 {#header_open|Illegal Behavior#}
5962 <p>
5963 Many operations in Zig trigger what is known as "Illegal Behavior" (IB). If Illegal Behavior is detected at
5964 compile-time, Zig emits a compile error and refuses to continue. Otherwise, when Illegal Behavior is not caught
5965 at compile-time, it falls into one of two categories.
5966 </p>
5967 <p>
5968 Some Illegal Behavior is <em>safety-checked</em>: this means that the compiler will insert "safety checks"
5969 anywhere that the Illegal Behavior may occur at runtime, to determine whether it is about to happen. If it
5970 is, the safety check "fails", which triggers a panic.
5971 </p>
5972 <p>
5973 All other Illegal Behavior is <em>unchecked</em>, meaning the compiler is unable to insert safety checks for
5974 it. If Unchecked Illegal Behavior is invoked at runtime, anything can happen: usually that will be some kind of
5975 crash, but the optimizer is free to make Unchecked Illegal Behavior do anything, such as calling arbitrary functions
5976 or clobbering arbitrary data. This is similar to the concept of "undefined behavior" in some other languages. Note that
5977 Unchecked Illegal Behavior still always results in a compile error if evaluated at {#link|comptime#}, because the Zig
5978 compiler is able to perform more sophisticated checks at compile-time than at runtime.
5979 </p>
5957 <p>5980 <p>
5958 Zig has many instances of undefined behavior. If undefined behavior is5981 Most Illegal Behavior is safety-checked. However, to facilitate optimizations, safety checks are disabled by default
5959 detected at compile-time, Zig emits a compile error and refuses to continue.5982 in the {#link|ReleaseFast#} and {#link|ReleaseSmall#} optimization modes. Safety checks can also be enabled or disabled
5960 Most undefined behavior that cannot be detected at compile-time can be detected5983 on a per-block basis, overriding the default for the current optimization mode, using {#link|@setRuntimeSafety#}. When
5961 at runtime. In these cases, Zig has safety checks. Safety checks can be disabled5984 safety checks are disabled, Safety-Checked Illegal Behavior behaves like Unchecked Illegal Behavior; that is, any behavior
5962 on a per-block basis with {#link|@setRuntimeSafety#}. The {#link|ReleaseFast#}5985 may result from invoking it.
5963 and {#link|ReleaseSmall#} build modes disable all safety checks (except where overridden
5964 by {#link|@setRuntimeSafety#}) in order to facilitate optimizations.
5965 </p>5986 </p>
5966 <p>5987 <p>
5967 When a safety check fails, Zig crashes with a stack trace, like this:5988 When a safety check fails, Zig's default panic handler crashes with a stack trace, like this:
5968 </p>5989 </p>
5969 {#code|test_undefined_behavior.zig#}5990 {#code|test_illegal_behavior.zig#}
59705991
5971 {#header_open|Reaching Unreachable Code#}5992 {#header_open|Reaching Unreachable Code#}
5972 <p>At compile-time:</p>5993 <p>At compile-time:</p>
...@@ -6332,7 +6353,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val...@@ -6332,7 +6353,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
6332 <p>6353 <p>
6333 {#syntax#}var{#endsyntax#} declarations inside functions are stored in the function's stack frame. Once a function returns,6354 {#syntax#}var{#endsyntax#} declarations inside functions are stored in the function's stack frame. Once a function returns,
6334 any {#link|Pointers#} to variables in the function's stack frame become invalid references, and6355 any {#link|Pointers#} to variables in the function's stack frame become invalid references, and
6335 dereferencing them becomes unchecked {#link|Undefined Behavior#}.6356 dereferencing them becomes unchecked {#link|Illegal Behavior#}.
6336 </p>6357 </p>
6337 <p>6358 <p>
6338 {#syntax#}var{#endsyntax#} declarations at the top level or in {#link|struct#} declarations are stored in the global6359 {#syntax#}var{#endsyntax#} declarations at the top level or in {#link|struct#} declarations are stored in the global
...@@ -6440,7 +6461,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val...@@ -6440,7 +6461,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
6440 The API documentation for functions and data structures should take great care to explain6461 The API documentation for functions and data structures should take great care to explain
6441 the ownership and lifetime semantics of pointers. Ownership determines whose responsibility it6462 the ownership and lifetime semantics of pointers. Ownership determines whose responsibility it
6442 is to free the memory referenced by the pointer, and lifetime determines the point at which6463 is to free the memory referenced by the pointer, and lifetime determines the point at which
6443 the memory becomes inaccessible (lest {#link|Undefined Behavior#} occur).6464 the memory becomes inaccessible (lest {#link|Illegal Behavior#} occur).
6444 </p>6465 </p>
6445 {#header_close#}6466 {#header_close#}
64466467
...@@ -6459,14 +6480,155 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val...@@ -6459,14 +6480,155 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
6459 {#builtin#}6480 {#builtin#}
6460 {#see_also|Build Mode#}6481 {#see_also|Build Mode#}
6461 {#header_close#}6482 {#header_close#}
6462 {#header_open|Root Source File#}6483 {#header_open|Compilation Model#}
6463 <p>TODO: explain how root source file finds other files</p>6484 <p>
6464 <p>TODO: pub fn main</p>6485 A Zig compilation is separated into <em>modules</em>. Each module is a collection of Zig source files,
6465 <p>TODO: pub fn panic</p>6486 one of which is the module's <em>root source file</em>. Each module can <em>depend</em> on any number of
6466 <p>TODO: if linking with libc you can use export fn main</p>6487 other modules, forming a directed graph (dependency loops between modules are allowed). If module A
6467 <p>TODO: order independent top level declarations</p>6488 depends on module B, then any Zig source file in module A can import the <em>root source file</em> of
6468 <p>TODO: lazy analysis</p>6489 module B using {#syntax#}@import{#endsyntax#} with the module's name. In essence, a module acts as an
6469 <p>TODO: using comptime { _ = @import() }</p>6490 alias to import a Zig source file (which might exist in a completely separate part of the filesystem).
6491 </p>
6492 <p>
6493 A simple Zig program compiled with <code>zig build-exe</code> has two key modules: the one containing your
6494 code, known as the "main" or "root" module, and the standard library. Your module <em>depends on</em>
6495 the standard library module under the name "std", which is what allows you to write
6496 {#syntax#}@import("std"){#endsyntax#}! In fact, every single module in a Zig compilation &mdash; including
6497 the standard library itself &mdash; implicitly depends on the standard library module under the name "std".
6498 </p>
6499 <p>
6500 The "root module" (the one provided by you in the <code>zig build-exe</code> example) has a special
6501 property. Like the standard library, it is implicitly made available to all modules (including itself),
6502 this time under the name "root". So, {#syntax#}@import("root"){#endsyntax#} will always be equivalent to
6503 {#syntax#}@import{#endsyntax#} of your "main" source file (often, but not necessarily, named
6504 <code>main.zig</code>).
6505 </p>
6506 {#header_open|Source File Structs#}
6507 <p>
6508 Every Zig source file is implicitly a {#syntax#}struct{#endsyntax#} declaration; you can imagine that
6509 the file's contents are literally surrounded by {#syntax#}struct { ... }{#endsyntax#}. This means that
6510 as well as declarations, the top level of a file is permitted to contain fields:
6511 </p>
6512 {#code|TopLevelFields.zig#}
6513 <p>
6514 Such files can be instantiated just like any other {#syntax#}struct{#endsyntax#} type. A file's "root
6515 struct type" can be referred to within that file using {#link|@This#}.
6516 </p>
6517 {#header_close#}
6518 {#header_open|File and Declaration Discovery#}
6519 <p>
6520 Zig places importance on the concept of whether any piece of code is <em>semantically analyzed</em>; in
6521 essence, whether the compiler "looks at" it. What code is analyzed is based on what files and
6522 declarations are "discovered" from a certain point. This process of "discovery" is based on a simple set
6523 of recursive rules:
6524 </p>
6525 <ul>
6526 <li>If a call to {#syntax#}@import{#endsyntax#} is analyzed, the file being imported is analyzed.</li>
6527 <li>If a type (including a file) is analyzed, all {#syntax#}comptime{#endsyntax#}, {#syntax#}usingnamespace{#endsyntax#}, and {#syntax#}export{#endsyntax#} declarations within it are analyzed.</li>
6528 <li>If a type (including a file) is analyzed, and the compilation is for a {#link|test|Zig Test#}, and the module the type is within is the root module of the compilation, then all {#syntax#}test{#endsyntax#} declarations within it are also analyzed.</li>
6529 <li>If a reference to a named declaration (i.e. a usage of it) is analyzed, the declaration being referenced is analyzed. Declarations are order-independent, so this reference may be above or below the declaration being referenced, or even in another file entirely.</li>
6530 </ul>
6531 <p>
6532 That's it! Those rules define how Zig files and declarations are discovered. All that remains is to
6533 understand where this process <em>starts</em>.
6534 </p>
6535 <p>
6536 The answer to that is the root of the standard library: every Zig compilation begins by analyzing the
6537 file <code>lib/std/std.zig</code>. This file contains a {#syntax#}comptime{#endsyntax#} declaration
6538 which imports {#syntax#}lib/std/start.zig{#endsyntax#}, and that file in turn uses
6539 {#syntax#}@import("root"){#endsyntax#} to reference the "root module"; so, the file you provide as your
6540 main module's root source file is effectively also a root, because the standard library will always
6541 reference it.
6542 </p>
6543 <p>
6544 It is often desirable to make sure that certain declarations &mdash; particularly {#syntax#}test{#endsyntax#}
6545 or {#syntax#}export{#endsyntax#} declarations &mdash; are discovered. Based on the above rules, a common
6546 strategy for this is to use {#syntax#}@import{#endsyntax#} within a {#syntax#}comptime{#endsyntax#} or
6547 {#syntax#}test{#endsyntax#} block:
6548 </p>
6549 {#syntax_block|zig|force_file_discovery.zig#}
6550comptime {
6551 // This will ensure that the file 'api.zig' is always discovered (as long as this file is discovered).
6552 // It is useful if 'api.zig' contains important exported declarations.
6553 _ = @import("api.zig");
6554
6555 // We could also have a file which contains declarations we only want to export depending on a comptime
6556 // condition. In that case, we can use an `if` statement here:
6557 if (builtin.os.tag == .windows) {
6558 _ = @import("windows_api.zig");
6559 }
6560}
6561
6562test {
6563 // This will ensure that the file 'tests.zig' is always discovered (as long as this file is discovered),
6564 // if this compilation is a test. It is useful if 'tests.zig' contains tests we want to ensure are run.
6565 _ = @import("tests.zig");
6566
6567 // We could also have a file which contains tests we only want to run depending on a comptime condition.
6568 // In that case, we can use an `if` statement here:
6569 if (builtin.os.tag == .windows) {
6570 _ = @import("windows_tests.zig");
6571 }
6572}
6573
6574const builtin = @import("builtin");
6575 {#end_syntax_block#}
6576 {#header_close#}
6577 {#header_open|Special Root Declarations#}
6578 <p>
6579 Because the root module's root source file is always accessible using
6580 {#syntax#}@import("root"){#endsyntax#}, is is sometimes used by libraries &mdash; including the Zig Standard
6581 Library &mdash; as a place for the program to expose some "global" information to that library. The Zig
6582 Standard Library will look for several declarations in this file.
6583 </p>
6584 {#header_open|Entry Point#}
6585 <p>
6586 When building an executable, the most important thing to be looked up in this file is the program's
6587 <em>entry point</em>. Most commonly, this is a function named {#syntax#}main{#endsyntax#}, which
6588 {#syntax#}std.start{#endsyntax#} will call just after performing important initialization work.
6589 </p>
6590 <p>
6591 Alternatively, the presence of a declaration named {#syntax#}_start{#endsyntax#} (for instance,
6592 {#syntax#}pub const _start = {};{#endsyntax#}) will disable the default {#syntax#}std.start{#endsyntax#}
6593 logic, allowing your root source file to export a low-level entry point as needed.
6594 </p>
6595 {#code|entry_point.zig#}
6596 <p>
6597 If the Zig compilation links libc, the {#syntax#}main{#endsyntax#} function can optionally be an
6598 {#syntax#}export fn{#endsyntax#} which matches the signature of the C <code>main</code> function:
6599 </p>
6600 {#code|libc_export_entry_point.zig#}
6601 <p>
6602 {#syntax#}std.start{#endsyntax#} may also use other entry point declarations in certain situations, such
6603 as {#syntax#}wWinMain{#endsyntax#} or {#syntax#}EfiMain{#endsyntax#}. Refer to the
6604 {#syntax#}lib/std/start.zig{#endsyntax#} logic for details of these declarations.
6605 </p>
6606 {#header_close#}
6607 {#header_open|Standard Library Options#}
6608 <p>
6609 The standard library also looks for a declaration in the root module's root source file named
6610 {#syntax#}std_options{#endsyntax#}. If present, this declaration is expected to be a struct of type
6611 {#syntax#}std.Options{#endsyntax#}, and allows the program to customize some standard library
6612 functionality, such as the {#syntax#}std.log{#endsyntax#} implementation.
6613 </p>
6614 {#code|std_options.zig#}
6615 {#header_close#}
6616 {#header_open|Panic Handler#}
6617 <p>
6618 The Zig Standard Library looks for a declaration named {#syntax#}panic{#endsyntax#} in the root module's
6619 root source file. If present, it is expected to be a namespace (container type) with declarations
6620 providing different panic handlers.
6621 </p>
6622 <p>
6623 See {#syntax#}std.debug.simple_panic{#endsyntax#} for a basic implementation of this namespace.
6624 </p>
6625 <p>
6626 Overriding how the panic handler actually outputs messages, but keeping the formatted safety panics
6627 which are enabled by default, can be easily achieved with {#syntax#}std.debug.FullPanic{#endsyntax#}:
6628 </p>
6629 {#code|panic_handler.zig#}
6630 {#header_close#}
6631 {#header_close#}
6470 {#header_close#}6632 {#header_close#}
6471 {#header_open|Zig Build System#}6633 {#header_open|Zig Build System#}
6472 <p>6634 <p>
...@@ -6728,10 +6890,10 @@ int foo(void) {...@@ -6728,10 +6890,10 @@ int foo(void) {
6728 <li>Supports all the syntax of the other two pointer types ({#syntax#}*T{#endsyntax#}) and ({#syntax#}[*]T{#endsyntax#}).</li>6890 <li>Supports all the syntax of the other two pointer types ({#syntax#}*T{#endsyntax#}) and ({#syntax#}[*]T{#endsyntax#}).</li>
6729 <li>Coerces to other pointer types, as well as {#link|Optional Pointers#}.6891 <li>Coerces to other pointer types, as well as {#link|Optional Pointers#}.
6730 When a C pointer is coerced to a non-optional pointer, safety-checked6892 When a C pointer is coerced to a non-optional pointer, safety-checked
6731 {#link|Undefined Behavior#} occurs if the address is 0.6893 {#link|Illegal Behavior#} occurs if the address is 0.
6732 </li>6894 </li>
6733 <li>Allows address 0. On non-freestanding targets, dereferencing address 0 is safety-checked6895 <li>Allows address 0. On non-freestanding targets, dereferencing address 0 is safety-checked
6734 {#link|Undefined Behavior#}. Optional C pointers introduce another bit to keep track of6896 {#link|Illegal Behavior#}. Optional C pointers introduce another bit to keep track of
6735 null, just like {#syntax#}?usize{#endsyntax#}. Note that creating an optional C pointer6897 null, just like {#syntax#}?usize{#endsyntax#}. Note that creating an optional C pointer
6736 is unnecessary as one can use normal {#link|Optional Pointers#}.6898 is unnecessary as one can use normal {#link|Optional Pointers#}.
6737 </li>6899 </li>
...@@ -7046,8 +7208,8 @@ fn readU32Be() u32 {}...@@ -7046,8 +7208,8 @@ fn readU32Be() u32 {}
7046 <ul>7208 <ul>
7047 <li>Omit any information that is redundant based on the name of the thing being documented.</li>7209 <li>Omit any information that is redundant based on the name of the thing being documented.</li>
7048 <li>Duplicating information onto multiple similar functions is encouraged because it helps IDEs and other tools provide better help text.</li>7210 <li>Duplicating information onto multiple similar functions is encouraged because it helps IDEs and other tools provide better help text.</li>
7049 <li>Use the word <strong>assume</strong> to indicate invariants that cause {#link|Undefined Behavior#} when violated.</li>7211 <li>Use the word <strong>assume</strong> to indicate invariants that cause <em>unchecked</em> {#link|Illegal Behavior#} when violated.</li>
7050 <li>Use the word <strong>assert</strong> to indicate invariants that cause <em>safety-checked</em> {#link|Undefined Behavior#} when violated.</li>7212 <li>Use the word <strong>assert</strong> to indicate invariants that cause <em>safety-checked</em> {#link|Illegal Behavior#} when violated.</li>
7051 </ul>7213 </ul>
7052 {#header_close#}7214 {#header_close#}
7053 {#header_close#}7215 {#header_close#}
...@@ -7443,8 +7605,8 @@ fn readU32Be() u32 {}...@@ -7443,8 +7605,8 @@ fn readU32Be() u32 {}
7443 In particular, inside a {#syntax#}nosuspend{#endsyntax#} scope:7605 In particular, inside a {#syntax#}nosuspend{#endsyntax#} scope:
7444 <ul>7606 <ul>
7445 <li>Using the {#syntax#}suspend{#endsyntax#} keyword results in a compile error.</li>7607 <li>Using the {#syntax#}suspend{#endsyntax#} keyword results in a compile error.</li>
7446 <li>Using {#syntax#}await{#endsyntax#} on a function frame which hasn't completed yet results in safety-checked {#link|Undefined Behavior#}.</li>7608 <li>Using {#syntax#}await{#endsyntax#} on a function frame which hasn't completed yet results in safety-checked {#link|Illegal Behavior#}.</li>
7447 <li>Calling an async function may result in safety-checked {#link|Undefined Behavior#}, because it's equivalent to <code>await async some_async_fn()</code>, which contains an {#syntax#}await{#endsyntax#}.</li>7609 <li>Calling an async function may result in safety-checked {#link|Illegal Behavior#}, because it's equivalent to <code>await async some_async_fn()</code>, which contains an {#syntax#}await{#endsyntax#}.</li>
7448 </ul>7610 </ul>
7449 Code inside a {#syntax#}nosuspend{#endsyntax#} scope does not cause the enclosing function to become an {#link|async function|Async Functions#}.7611 Code inside a {#syntax#}nosuspend{#endsyntax#} scope does not cause the enclosing function to become an {#link|async function|Async Functions#}.
7450 <ul>7612 <ul>
doc/langref/TopLevelFields.zig created+18
...@@ -0,0 +1,18 @@
1//! Because this file contains fields, it is a type which is intended to be instantiated, and so
2//! is named in TitleCase instead of snake_case by convention.
3
4foo: u32,
5bar: u64,
6
7/// `@This()` can be used to refer to this struct type. In files with fields, it is quite common to
8/// name the type here, so it can be easily referenced by other declarations in this file.
9const TopLevelFields = @This();
10
11pub fn init(val: u32) TopLevelFields {
12 return .{
13 .foo = val,
14 .bar = val * 10,
15 };
16}
17
18// syntax
doc/langref/entry_point.zig created+20
...@@ -0,0 +1,20 @@
1/// `std.start` imports this file using `@import("root")`, and uses this declaration as the program's
2/// user-provided entry point. It can return any of the following types:
3/// * `void`
4/// * `E!void`, for any error set `E`
5/// * `u8`
6/// * `E!u8`, for any error set `E`
7/// Returning a `void` value from this function will exit with code 0.
8/// Returning a `u8` value from this function will exit with the given status code.
9/// Returning an error value from this function will print an Error Return Trace and exit with code 1.
10pub fn main() void {
11 std.debug.print("Hello, World!\n", .{});
12}
13
14// If uncommented, this declaration would suppress the usual std.start logic, causing
15// the `main` declaration above to be ignored.
16//pub const _start = {};
17
18const std = @import("std");
19
20// exe=succeed
doc/langref/libc_export_entry_point.zig created+10
...@@ -0,0 +1,10 @@
1pub export fn main(argc: c_int, argv: [*]const [*:0]const u8) c_int {
2 const args = argv[0..@intCast(argc)];
3 std.debug.print("Hello! argv[0] is '{s}'\n", .{args[0]});
4 return 0;
5}
6
7const std = @import("std");
8
9// exe=succeed
10// link_libc
doc/langref/panic_handler.zig created+18
...@@ -0,0 +1,18 @@
1pub fn main() void {
2 @setRuntimeSafety(true);
3 var x: u8 = 255;
4 // Let's overflow this integer!
5 x += 1;
6}
7
8pub const panic = std.debug.FullPanic(myPanic);
9
10fn myPanic(msg: []const u8, first_trace_addr: ?usize) noreturn {
11 _ = first_trace_addr;
12 std.debug.print("Panic! {s}\n", .{msg});
13 std.process.exit(1);
14}
15
16const std = @import("std");
17
18// exe=fail
doc/langref/std_options.zig created+25
...@@ -0,0 +1,25 @@
1/// The presence of this declaration allows the program to override certain behaviors of the standard library.
2/// For a full list of available options, see the documentation for `std.Options`.
3pub const std_options: std.Options = .{
4 // By default, in safe build modes, the standard library will attach a segfault handler to the program to
5 // print a helpful stack trace if a segmentation fault occurs. Here, we can disable this, or even enable
6 // it in unsafe build modes.
7 .enable_segfault_handler = true,
8 // This is the logging function used by `std.log`.
9 .logFn = myLogFn,
10};
11
12fn myLogFn(
13 comptime level: std.log.Level,
14 comptime scope: @Type(.enum_literal),
15 comptime format: []const u8,
16 args: anytype,
17) void {
18 // We could do anything we want here!
19 // ...but actually, let's just call the default implementation.
20 std.log.defaultLog(level, scope, format, args);
21}
22
23const std = @import("std");
24
25// syntax
doc/langref/test_illegal_behavior.zig created+5
...@@ -0,0 +1,5 @@
1test "safety check" {
2 unreachable;
3}
4
5// test_error=reached unreachable code
doc/langref/test_setRuntimeSafety_builtin.zig+2-2
...@@ -2,7 +2,7 @@ test "@setRuntimeSafety" {...@@ -2,7 +2,7 @@ test "@setRuntimeSafety" {
2 // The builtin applies to the scope that it is called in. So here, integer overflow2 // The builtin applies to the scope that it is called in. So here, integer overflow
3 // will not be caught in ReleaseFast and ReleaseSmall modes:3 // will not be caught in ReleaseFast and ReleaseSmall modes:
4 // var x: u8 = 255;4 // var x: u8 = 255;
5 // x += 1; // undefined behavior in ReleaseFast/ReleaseSmall modes.5 // x += 1; // Unchecked Illegal Behavior in ReleaseFast/ReleaseSmall modes.
6 {6 {
7 // However this block has safety enabled, so safety checks happen here,7 // However this block has safety enabled, so safety checks happen here,
8 // even in ReleaseFast and ReleaseSmall modes.8 // even in ReleaseFast and ReleaseSmall modes.
...@@ -15,7 +15,7 @@ test "@setRuntimeSafety" {...@@ -15,7 +15,7 @@ test "@setRuntimeSafety" {
15 // would not be caught in any build mode.15 // would not be caught in any build mode.
16 @setRuntimeSafety(false);16 @setRuntimeSafety(false);
17 // var x: u8 = 255;17 // var x: u8 = 255;
18 // x += 1; // undefined behavior in all build modes.18 // x += 1; // Unchecked Illegal Behavior in all build modes.
19 }19 }
20 }20 }
21}21}
doc/langref/test_undefined_behavior.zig deleted-5
...@@ -1,5 +0,0 @@
1test "safety check" {
2 unreachable;
3}
4
5// test_error=reached unreachable code