diff --git a/doc/langref.html.in b/doc/langref.html.in index 8b7e9b87e6..3516c08eb0 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -1290,13 +1290,39 @@ test "expectError demo" { A variable is a unit of {#link|Memory#} storage.
- Variables are never allowed to shadow identifiers from an outer scope. -
-It is generally preferable to use {#syntax#}const{#endsyntax#} rather than {#syntax#}var{#endsyntax#} when declaring a variable. This causes less work for both humans and computers to do when reading code, and creates more optimization opportunities.
+ + {#header_open|Identifiers#} ++ Variable identifiers are never allowed to shadow identifiers from an outer scope. +
++ Identifiers must start with an alphabetic character or underscore and may be followed + by any number of alphanumeric characters or underscores. + They must not overlap with any keywords. See {#link|Keyword Reference#}. +
++ If a name that does not fit these requirements is needed, such as for linking with external libraries, the {#syntax#}@""{#endsyntax#} syntax may be used. +
+ {#code_begin|syntax#} +const @"identifier with spaces in it" = 0xff; +const @"1SmallStep4Man" = 112358; + +const c = @import("std").c; +pub extern "c" fn @"error"() anyopaque; +pub extern "c" fn @"fstat$INODE64"(fd: c.fd_t, buf: *c.Stat) c_int; + +const Color = enum { + red, + @"really red", +}; +const color: Color = .@"really red"; + {#code_end#} + {#header_close#} + {#header_open|Container Level Variables#}Container level variables have static lifetime and are order-independent and lazily analyzed. @@ -1481,7 +1507,7 @@ fn divide(a: i32, b: i32) i32 {
Operators such as {#syntax#}+{#endsyntax#} and {#syntax#}-{#endsyntax#} cause undefined behavior on - integer overflow. Alternative operators are provided for wrapping and saturating arithmetic on all targets. + integer overflow. Alternative operators are provided for wrapping and saturating arithmetic on all targets. {#syntax#}+%{#endsyntax#} and {#syntax#}-%{#endsyntax#} perform wrapping arithmetic while {#syntax#}+|{#endsyntax#} and {#syntax#}-|{#endsyntax#} perform saturating arithmetic.
@@ -2488,32 +2514,32 @@ test "null terminated array" { or using the shorthand function {#syntax#}std.meta.Vector{#endsyntax#}.- Vectors support the same builtin operators as their underlying base types. These operations are performed + Vectors support the same builtin operators as their underlying base types. These operations are performed element-wise, and return a vector of the same length as the input vectors. This includes:
- It is prohibited to use a math operator on a mixture of scalars (individual numbers) and vectors. - Zig provides the {#link|@splat#} builtin to easily convert from scalars to vectors, and it supports {#link|@reduce#} - and array indexing syntax to convert from vectors to scalars. Vectors also support assignment to and from + It is prohibited to use a math operator on a mixture of scalars (individual numbers) and vectors. + Zig provides the {#link|@splat#} builtin to easily convert from scalars to vectors, and it supports {#link|@reduce#} + and array indexing syntax to convert from vectors to scalars. Vectors also support assignment to and from fixed-length arrays with comptime known length.
For rearranging elements within and between vectors, Zig provides the {#link|@shuffle#} and {#link|@select#} functions.
- Operations on vectors shorter than the target machine's native SIMD size will typically compile to single SIMD - instructions, while vectors longer than the target machine's native SIMD size will compile to multiple SIMD - instructions. If a given operation doesn't have SIMD support on the target architecture, the compiler will default - to operating on each vector element one at a time. Zig supports any comptime-known vector length up to 2^32-1, - although small powers of two (2-64) are most typical. Note that excessively long vector lengths (e.g. 2^20) may + Operations on vectors shorter than the target machine's native SIMD size will typically compile to single SIMD + instructions, while vectors longer than the target machine's native SIMD size will compile to multiple SIMD + instructions. If a given operation doesn't have SIMD support on the target architecture, the compiler will default + to operating on each vector element one at a time. Zig supports any comptime-known vector length up to 2^32-1, + although small powers of two (2-64) are most typical. Note that excessively long vector lengths (e.g. 2^20) may result in compiler crashes on current versions of Zig.
{#code_begin|test|vector_example#} @@ -2563,7 +2589,7 @@ test "Conversion between vectors, arrays, and slices" { TODO consider suggesting std.MultiArrayList {#see_also|@splat|@shuffle|@select|@reduce#} - + {#header_close#} {#header_open|Pointers#} @@ -2981,8 +3007,8 @@ test "null terminated slice" { } {#code_end#}- Sentinel-terminated slices can also be created using a variation of the slice syntax - {#syntax#}data[start..end :x]{#endsyntax#}, where {#syntax#}data{#endsyntax#} is a many-item pointer, + Sentinel-terminated slices can also be created using a variation of the slice syntax + {#syntax#}data[start..end :x]{#endsyntax#}, where {#syntax#}data{#endsyntax#} is a many-item pointer, array or slice and {#syntax#}x{#endsyntax#} is the sentinel value.
{#code_begin|test|null_terminated_slicing#} @@ -2999,7 +3025,7 @@ test "null terminated slicing" { } {#code_end#}- Sentinel-terminated slicing asserts that the element in the sentinel position of the backing data is + Sentinel-terminated slicing asserts that the element in the sentinel position of the backing data is actually the sentinel value. If this is not the case, safety-protected {#link|Undefined Behavior#} results.
{#code_begin|test_safety|sentinel mismatch#} @@ -3008,10 +3034,10 @@ const expect = std.testing.expect; test "sentinel mismatch" { var array = [_]u8{ 3, 2, 1, 0 }; - - // Creating a sentinel-terminated slice from the array with a length of 2 - // will result in the value `1` occupying the sentinel element position. - // This does not match the indicated sentinel value of `0` and will lead + + // Creating a sentinel-terminated slice from the array with a length of 2 + // will result in the value `1` occupying the sentinel element position. + // This does not match the indicated sentinel value of `0` and will lead // to a runtime panic. var runtime_length: usize = 2; const slice = array[0..runtime_length :0]; @@ -3159,7 +3185,7 @@ test "linked list" { .last = &node, .len = 1, }; - + // When using a pointer to a struct, fields can be accessed directly, // without explicitly dereferencing the pointer. // So you can do @@ -3491,7 +3517,7 @@ fn dump(args: anytype) !void {The fields are implicitly named using numbers starting from 0. Because their names are integers, - the {#syntax#}@"0"{#endsyntax#} syntax must be used to access them. Names inside {#syntax#}@""{#endsyntax#} are always recognised as identifiers. + the {#syntax#}@"0"{#endsyntax#} syntax must be used to access them. Names inside {#syntax#}@""{#endsyntax#} are always recognised as {#link|identifiers|Identifiers#}.
Like arrays, tuples have a .len field, can be indexed and work with the ++ and ** operators. They can also be iterated over with {#link|inline for#}. @@ -3980,7 +4006,7 @@ test "labeled break from labeled block expression" { {#see_also|Labeled while|Labeled for#} {#header_open|Shadowing#} -
Identifiers are never allowed to "hide" other identifiers by using the same name:
+{#link|Identifiers#} are never allowed to "hide" other identifiers by using the same name:
{#code_begin|test_err|local shadows declaration#} const pi = 3.14; @@ -3992,8 +4018,8 @@ test "inside test block" { } {#code_end#}- Because of this, when you read Zig code you can always rely on an identifier to consistently mean - the same thing within the scope it is defined. Note that you can, however, use the same name if + Because of this, when you read Zig code you can always rely on an identifier to consistently mean + the same thing within the scope it is defined. Note that you can, however, use the same name if the scopes are separate:
{#code_begin|test|test_scopes#} @@ -4031,7 +4057,7 @@ test "switch simple" { 1, 2, 3 => 0, // Ranges can be specified using the ... syntax. These are inclusive - // both ends. + // of both ends. 5...100 => 1, // Branches can be arbitrarily complex. @@ -4803,7 +4829,7 @@ test "errdefer unwinding" { {#header_open|Basics#} {#code_begin|test|test_unreachable#} -// unreachable is used to assert that control flow will never happen upon a +// unreachable is used to assert that control flow will never reach a // particular location: test "basic math" { const x = 1; @@ -6771,8 +6797,7 @@ test "variable values" { generic data structure.- Here is an example of a generic {#syntax#}List{#endsyntax#} data structure, that we will instantiate with - the type {#syntax#}i32{#endsyntax#}. In Zig we refer to the type as {#syntax#}List(i32){#endsyntax#}. + Here is an example of a generic {#syntax#}List{#endsyntax#} data structure.
{#code_begin|syntax#} fn List(comptime T: type) type { @@ -6781,27 +6806,46 @@ fn List(comptime T: type) type { len: usize, }; } - {#code_end#} -- That's it. It's a function that returns an anonymous {#syntax#}struct{#endsyntax#}. For the purposes of error messages - and debugging, Zig infers the name {#syntax#}"List(i32)"{#endsyntax#} from the function name and parameters invoked when creating - the anonymous struct. -
-- To keep the language small and uniform, all aggregate types in Zig are anonymous. To give a type - a name, we assign it to a constant: -
- {#code_begin|syntax#} -const Node = struct { - next: *Node, - name: []u8, + +// The generic List data structure can be instantiated by passing in a type: +var buffer: [10]i32 = undefined; +var list = List(i32){ + .items = &buffer, + .len = 0, }; {#code_end#}- This works because all top level declarations are order-independent, and as long as there isn't - an actual infinite regression, values can refer to themselves, directly or indirectly. In this case, - {#syntax#}Node{#endsyntax#} refers to itself as a pointer, which is not actually an infinite regression, so - it works fine. + That's it. It's a function that returns an anonymous {#syntax#}struct{#endsyntax#}. + To keep the language small and uniform, all aggregate types in Zig are anonymous. + For the purposes of error messages and debugging, Zig infers the name + {#syntax#}"List(i32)"{#endsyntax#} from the function name and parameters invoked when creating + the anonymous struct. +
++ To explicitly give a type a name, we assign it to a constant. +
+ {#code_begin|syntax#} +const Node = struct { + next: ?*Node, + name: []const u8, +}; + +var node_a = Node{ + .next = null, + .name = &"Node A", +}; + +var node_b = Node{ + .next = &node_a, + .name = &"Node B", +}; + {#code_end#} ++ In this example, the {#syntax#}Node{#endsyntax#} struct refers to itself. + This works because all top level declarations are order-independent. + As long as the compiler can determine the size of the struct, it is free to refer to itself. + In this case, {#syntax#}Node{#endsyntax#} refers to itself as a pointer, which has a + well-defined size at compile time, so it works fine.
{#header_close#} {#header_open|Case Study: print in Zig#} @@ -7214,10 +7258,10 @@ test "global assembly" { provided explicitly by the caller, and it can be suspended and resumed any number of times.- The code following the {#syntax#}async{#endsyntax#} callsite runs immediately after the async - function first suspends. When the return value of the async function is needed, - the calling code can {#syntax#}await{#endsyntax#} on the async function frame. - This will suspend the calling code until the async function completes, at which point + The code following the {#syntax#}async{#endsyntax#} callsite runs immediately after the async + function first suspends. When the return value of the async function is needed, + the calling code can {#syntax#}await{#endsyntax#} on the async function frame. + This will suspend the calling code until the async function completes, at which point execution resumes just after the {#syntax#}await{#endsyntax#} callsite.
@@ -7327,8 +7371,8 @@ fn testResumeFromSuspend(my_result: *i32) void { in standard code.
- However, it is possible to have an {#syntax#}async{#endsyntax#} call - without a matching {#syntax#}await{#endsyntax#}. Upon completion of the async function, + However, it is possible to have an {#syntax#}async{#endsyntax#} call + without a matching {#syntax#}await{#endsyntax#}. Upon completion of the async function, execution would continue at the most recent {#syntax#}async{#endsyntax#} callsite or {#syntax#}resume{#endsyntax#} callsite, and the return value of the async function would be lost.
@@ -7365,8 +7409,8 @@ fn func() void {{#syntax#}await{#endsyntax#} is a suspend point, and takes as an operand anything that - coerces to {#syntax#}anyframe->T{#endsyntax#}. Calling {#syntax#}await{#endsyntax#} on - the frame of an async function will cause execution to continue at the + coerces to {#syntax#}anyframe->T{#endsyntax#}. Calling {#syntax#}await{#endsyntax#} on + the frame of an async function will cause execution to continue at the {#syntax#}await{#endsyntax#} callsite once the target function completes.
@@ -8291,8 +8335,8 @@ fn internalName() callconv(.C) void {} {#code_begin|obj#} export fn foo() void {} {#code_end#} -
Note that even when using {#syntax#}export{#endsyntax#}, {#syntax#}@"foo"{#endsyntax#} syntax can - be used to choose any string for the symbol name:
+Note that even when using {#syntax#}export{#endsyntax#}, the {#syntax#}@"foo"{#endsyntax#} syntax for + {#link|identifiers|Identifiers#} can be used to choose any string for the symbol name:
{#code_begin|obj#} export fn @"A function name that is a complete sentence."() void {} {#code_end#} @@ -8591,7 +8635,9 @@ test "integer cast panic" { {#header_open|@intToPtr#}{#syntax#}@intToPtr(comptime DestType: type, address: usize) DestType{#endsyntax#}
- Converts an integer to a {#link|pointer|Pointers#}. To convert the other way, use {#link|@ptrToInt#}. + Converts an integer to a {#link|pointer|Pointers#}. To convert the other way, use {#link|@ptrToInt#}. Casting an address of 0 to a destination type + which in not {#link|optional|Optional Pointers#} and does not have the {#syntax#}allowzero{#endsyntax#} attribute will result in a + {#link|Pointer Cast Invalid Null#} panic when runtime safety checks are enabled.
If the destination pointer type does not allow address zero and {#syntax#}address{#endsyntax#} @@ -8705,7 +8751,8 @@ test "@wasmMemoryGrow" {
{#syntax#}@mod(numerator: T, denominator: T) T{#endsyntax#}
Modulus division. For unsigned integers this is the same as - {#syntax#}numerator % denominator{#endsyntax#}. Caller guarantees {#syntax#}denominator > 0{#endsyntax#}. + {#syntax#}numerator % denominator{#endsyntax#}. Caller guarantees {#syntax#}denominator > 0{#endsyntax#}, otherwise the + operation will result in a {#link|Remainder Division by Zero#} when runtime safety checks are enabled.
{#syntax#}@panic(message: []const u8) noreturn{#endsyntax#}
@@ -8830,7 +8877,8 @@ pub const PrefetchOptions = struct {
{#syntax#}@rem(numerator: T, denominator: T) T{#endsyntax#}
Remainder division. For unsigned integers this is the same as - {#syntax#}numerator % denominator{#endsyntax#}. Caller guarantees {#syntax#}denominator > 0{#endsyntax#}. + {#syntax#}numerator % denominator{#endsyntax#}. Caller guarantees {#syntax#}denominator > 0{#endsyntax#}, otherwise the + operation will result in a {#link|Remainder Division by Zero#} when runtime safety checks are enabled.
{#syntax#}@setCold(is_cold: bool){#endsyntax#}
+ {#syntax#}@setCold(comptime is_cold: bool){#endsyntax#}
Tells the optimizer that a function is rarely called.
{#header_close#} {#header_open|@setEvalBranchQuota#} -{#syntax#}@setEvalBranchQuota(new_quota: u32){#endsyntax#}
+ {#syntax#}@setEvalBranchQuota(comptime new_quota: u32){#endsyntax#}
Changes the maximum number of backwards branches that compile-time code execution can use before giving up and making a compile error. @@ -8914,7 +8962,7 @@ test "foo" { {#header_close#} {#header_open|@setFloatMode#} -
{#syntax#}@setFloatMode(mode: @import("std").builtin.FloatMode){#endsyntax#}
+ {#syntax#}@setFloatMode(comptime mode: @import("std").builtin.FloatMode){#endsyntax#}
Sets the floating point mode of the current scope. Possible values are:
@@ -8949,7 +8997,7 @@ pub const FloatMode = enum { {#header_close#} {#header_open|@setRuntimeSafety#} -{#syntax#}@setRuntimeSafety(safety_on: bool) void{#endsyntax#}
+ {#syntax#}@setRuntimeSafety(comptime safety_on: bool) void{#endsyntax#}
Sets whether runtime safety checks are enabled for the scope that contains the function call.
@@ -9010,7 +9058,7 @@ test "@setRuntimeSafety" { {#see_also|@shlExact|@shrExact#} {#header_close#} - + {#header_open|@shrExact#}{#syntax#}@shrExact(value: T, shift_amt: Log2T) T{#endsyntax#}
@@ -9341,7 +9389,7 @@ fn doTheTest() !void { If no overflow or underflow occurs, returns {#syntax#}false{#endsyntax#}.
{#header_close#} - + {#header_open|@tagName#}{#syntax#}@tagName(value: anytype) [:0]const u8{#endsyntax#}