zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit ce3679aa45710261afa2e519cfc55164541643fc (tree)
parent da063ebd9660de246b52811913defe2b8dd074cd
Author: Roman FroĊ‚ow <rofrol@gmail.com>
Date:   Wed, 23 Jun 2021 07:45:36 +0200

Docs clarification: local static variable (#8381)


Diffstat:
Mdoc/langref.html.in | 79++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------
1 file changed, 58 insertions(+), 21 deletions(-)

diff --git a/doc/langref.html.in b/doc/langref.html.in @@ -258,7 +258,7 @@ pub fn main() !void { <p> The code sample begins by adding Zig's Standard Library to the build using the {#link|@import#} builtin function. The {#syntax#}@import("std"){#endsyntax#} function call creates a structure to represent the Standard Library. - The code then makes a {#link|top-level declaration|Global Variables#} of a + The code then {#link|declares|Container level Variables#} a {#link|constant identifier|Assignment#}, named <code>std</code>, for easy access to <a href="https://github.com/ziglang/zig/wiki/FAQ#where-is-the-documentation-for-the-zig-standard-library">Zig's standard library</a>. </p> @@ -802,7 +802,7 @@ const hello_world_in_c = const x = 1234; fn foo() void { - // It works at global scope as well as inside functions. + // It works at file scope as well as inside functions. const y = 5678; // Once assigned, an identifier cannot be changed. @@ -872,18 +872,18 @@ test "init with undefined" { {#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. </p> - {#header_open|Global Variables#} + {#header_open|Container Level Variables#} <p> - Global variables are considered to be a top level declaration, which means that they are - order-independent and lazily analyzed. The initialization value of global variables is implicitly - {#link|comptime#}. If a global variable is {#syntax#}const{#endsyntax#} then its value is + Container level variables have static lifetime and are order-independent and lazily analyzed. + The initialization value of container level variables is implicitly + {#link|comptime#}. If a container level variable is {#syntax#}const{#endsyntax#} then its value is {#syntax#}comptime{#endsyntax#}-known, otherwise it is runtime-known. </p> - {#code_begin|test|global_variables#} + {#code_begin|test|container_level_variables#} var y: i32 = add(10, x); const x: i32 = add(12, 34); -test "global variables" { +test "container level variables" { try expect(x == 46); try expect(y == 56); } @@ -896,27 +896,51 @@ const std = @import("std"); const expect = std.testing.expect; {#code_end#} <p> - Global variables may be declared inside a {#link|struct#}, {#link|union#}, or {#link|enum#}: + Container level variables may be declared inside a {#link|struct#}, {#link|union#}, or {#link|enum#}: </p> - {#code_begin|test|namespaced_global#} + {#code_begin|test|namespaced_container_level_variable#} const std = @import("std"); const expect = std.testing.expect; -test "namespaced global variable" { +test "namespaced container level variable" { try expect(foo() == 1235); try expect(foo() == 1236); } +const S = struct { + var x: i32 = 1234; +}; + fn foo() i32 { - const S = struct { - var x: i32 = 1234; - }; S.x += 1; return S.x; } {#code_end#} + {#header_close#} + + {#header_open|Static Local Variables#} + <p> + It is also possible to have local variables with static lifetime by using containers inside functions. + </p> + {#code_begin|test|static_local_variable#} + const std = @import("std"); + const expect = std.testing.expect; + + test "static local variable" { + expect(foo() == 1235); + expect(foo() == 1236); + } + + fn foo() i32 { + const S = struct { + var x: i32 = 1234; + }; + S.x += 1; + return S.x; + } + {#code_end#} <p> - The {#syntax#}extern{#endsyntax#} keyword can be used to link against a variable that is exported + The {#syntax#}extern{#endsyntax#} keyword or {#link|@extern#} builtin function can be used to link against a variable that is exported from another object. The {#syntax#}export{#endsyntax#} keyword or {#link|@export#} builtin function can be used to make a variable available to other objects at link time. In both cases, the type of the variable must be C ABI compatible. @@ -948,7 +972,7 @@ fn testTls(context: void) void { } {#code_end#} <p> - For {#link|Single Threaded Builds#}, all thread local variables are treated as {#link|Global Variables#}. + For {#link|Single Threaded Builds#}, all thread local variables are treated as regular {#link|Container Level Variables#}. </p> <p> Thread local variables may not be {#syntax#}const{#endsyntax#}. @@ -2467,7 +2491,7 @@ test "dot product" { try expect(Vec3.dot(v1, v2) == 0.0); } -// Structs can have global declarations. +// Structs can have declarations. // Structs can have 0 fields. const Empty = struct { pub const PI = 3.14; @@ -5684,7 +5708,7 @@ test "@intToPtr for pointer to zero bit type" { {#header_open|usingnamespace#} <p> - {#syntax#}usingnamespace{#endsyntax#} is a top level declaration that imports all the public declarations of + {#syntax#}usingnamespace{#endsyntax#} is a declaration that imports all the public declarations of the operand, which must be a {#link|struct#}, {#link|union#}, or {#link|enum#}, into the current scope: </p> {#code_begin|test|usingnamespace#} @@ -5695,6 +5719,19 @@ test "using std namespace" { } {#code_end#} <p> + {#syntax#}usingnamespace{#endsyntax#} can also be used in containers: + </p> + {#code_begin|test|usingnamespace_inside_struct#} +test "using namespace inside struct" { + const L = struct { + usingnamespace struct { + pub fn f() void {} + }; + }; + L.f(); +} + {#code_end#} + <p> Instead of the above pattern, it is generally recommended to explicitly alias individual declarations. However, {#syntax#}usingnamespace{#endsyntax#} has an important use case when organizing the public API of a file or package. For example, one might have <code>c.zig</code> with all of the @@ -6044,7 +6081,7 @@ test "fibonacci" { </p> <p> - In the global scope (outside of any function), all expressions are implicitly + At container level (outside of any function), all expressions are implicitly {#syntax#}comptime{#endsyntax#} expressions. This means that we can use functions to initialize complex static data. For example: </p> @@ -8529,7 +8566,7 @@ fn List(comptime T: type) type { } {#code_end#} <p> - When {#syntax#}@This(){#endsyntax#} is used at global scope, it returns a reference to the + When {#syntax#}@This(){#endsyntax#} is used at file scope, it returns a reference to the struct that corresponds to the current file. </p> {#header_close#} @@ -8744,7 +8781,7 @@ pub fn build(b: *Builder) void { {#header_open|Single Threaded Builds#} <p>Zig has a compile option <code>--single-threaded</code> which has the following effects:</p> <ul> - <li>All {#link|Thread Local Variables#} are treated as {#link|Global Variables#}.</li> + <li>All {#link|Thread Local Variables#} are treated as regular {#link|Container Level Variables#}.</li> <li>The overhead of {#link|Async Functions#} becomes equivalent to function call overhead.</li> <li>The {#syntax#}@import("builtin").single_threaded{#endsyntax#} becomes {#syntax#}true{#endsyntax#} and therefore various userland APIs which read this variable become more efficient.