authorgravatar for rofrol@gmail.comRoman Frołow <rofrol@gmail.com> 2021-06-23 07:45:36+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2021-06-23 08:45:36+03:00
logce3679aa45710261afa2e519cfc55164541643fc
treebf567468b0e1fd09dfa2720df082a5461867506b
parentda063ebd9660de246b52811913defe2b8dd074cd
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Docs clarification: local static variable (#8381)


1 files changed, 58 insertions(+), 21 deletions(-)

doc/langref.html.in+58-21
......@@ -258,7 +258,7 @@ pub fn main() !void {
258258 <p>
259259 The code sample begins by adding Zig's Standard Library to the build using the {#link|@import#} builtin function.
260260 The {#syntax#}@import("std"){#endsyntax#} function call creates a structure to represent the Standard Library.
261 The code then makes a {#link|top-level declaration|Global Variables#} of a
261 The code then {#link|declares|Container level Variables#} a
262262 {#link|constant identifier|Assignment#}, named <code>std</code>, for easy access to
263263 <a href="https://github.com/ziglang/zig/wiki/FAQ#where-is-the-documentation-for-the-zig-standard-library">Zig's standard library</a>.
264264 </p>
......@@ -802,7 +802,7 @@ const hello_world_in_c =
802802const x = 1234;
803803
804804fn foo() void {
805 // It works at global scope as well as inside functions.
805 // It works at file scope as well as inside functions.
806806 const y = 5678;
807807
808808 // Once assigned, an identifier cannot be changed.
......@@ -872,18 +872,18 @@ test "init with undefined" {
872872 {#syntax#}var{#endsyntax#} when declaring a variable. This causes less work for both
873873 humans and computers to do when reading code, and creates more optimization opportunities.
874874 </p>
875 {#header_open|Global Variables#}
875 {#header_open|Container Level Variables#}
876876 <p>
877 Global variables are considered to be a top level declaration, which means that they are
878 order-independent and lazily analyzed. The initialization value of global variables is implicitly
879 {#link|comptime#}. If a global variable is {#syntax#}const{#endsyntax#} then its value is
877 Container level variables have static lifetime and are order-independent and lazily analyzed.
878 The initialization value of container level variables is implicitly
879 {#link|comptime#}. If a container level variable is {#syntax#}const{#endsyntax#} then its value is
880880 {#syntax#}comptime{#endsyntax#}-known, otherwise it is runtime-known.
881881 </p>
882 {#code_begin|test|global_variables#}
882 {#code_begin|test|container_level_variables#}
883883var y: i32 = add(10, x);
884884const x: i32 = add(12, 34);
885885
886test "global variables" {
886test "container level variables" {
887887 try expect(x == 46);
888888 try expect(y == 56);
889889}
......@@ -896,27 +896,51 @@ const std = @import("std");
896896const expect = std.testing.expect;
897897 {#code_end#}
898898 <p>
899 Global variables may be declared inside a {#link|struct#}, {#link|union#}, or {#link|enum#}:
899 Container level variables may be declared inside a {#link|struct#}, {#link|union#}, or {#link|enum#}:
900900 </p>
901 {#code_begin|test|namespaced_global#}
901 {#code_begin|test|namespaced_container_level_variable#}
902902const std = @import("std");
903903const expect = std.testing.expect;
904904
905test "namespaced global variable" {
905test "namespaced container level variable" {
906906 try expect(foo() == 1235);
907907 try expect(foo() == 1236);
908908}
909909
910const S = struct {
911 var x: i32 = 1234;
912};
913
910914fn foo() i32 {
911 const S = struct {
912 var x: i32 = 1234;
913 };
914915 S.x += 1;
915916 return S.x;
916917}
918 {#code_end#}
919 {#header_close#}
920
921 {#header_open|Static Local Variables#}
922 <p>
923 It is also possible to have local variables with static lifetime by using containers inside functions.
924 </p>
925 {#code_begin|test|static_local_variable#}
926 const std = @import("std");
927 const expect = std.testing.expect;
928
929 test "static local variable" {
930 expect(foo() == 1235);
931 expect(foo() == 1236);
932 }
933
934 fn foo() i32 {
935 const S = struct {
936 var x: i32 = 1234;
937 };
938 S.x += 1;
939 return S.x;
940 }
917941 {#code_end#}
918942 <p>
919 The {#syntax#}extern{#endsyntax#} keyword can be used to link against a variable that is exported
943 The {#syntax#}extern{#endsyntax#} keyword or {#link|@extern#} builtin function can be used to link against a variable that is exported
920944 from another object. The {#syntax#}export{#endsyntax#} keyword or {#link|@export#} builtin function
921945 can be used to make a variable available to other objects at link time. In both cases,
922946 the type of the variable must be C ABI compatible.
......@@ -948,7 +972,7 @@ fn testTls(context: void) void {
948972}
949973 {#code_end#}
950974 <p>
951 For {#link|Single Threaded Builds#}, all thread local variables are treated as {#link|Global Variables#}.
975 For {#link|Single Threaded Builds#}, all thread local variables are treated as regular {#link|Container Level Variables#}.
952976 </p>
953977 <p>
954978 Thread local variables may not be {#syntax#}const{#endsyntax#}.
......@@ -2467,7 +2491,7 @@ test "dot product" {
24672491 try expect(Vec3.dot(v1, v2) == 0.0);
24682492}
24692493
2470// Structs can have global declarations.
2494// Structs can have declarations.
24712495// Structs can have 0 fields.
24722496const Empty = struct {
24732497 pub const PI = 3.14;
......@@ -5684,7 +5708,7 @@ test "@intToPtr for pointer to zero bit type" {
56845708
56855709 {#header_open|usingnamespace#}
56865710 <p>
5687 {#syntax#}usingnamespace{#endsyntax#} is a top level declaration that imports all the public declarations of
5711 {#syntax#}usingnamespace{#endsyntax#} is a declaration that imports all the public declarations of
56885712 the operand, which must be a {#link|struct#}, {#link|union#}, or {#link|enum#}, into the current scope:
56895713 </p>
56905714 {#code_begin|test|usingnamespace#}
......@@ -5692,6 +5716,19 @@ usingnamespace @import("std");
56925716
56935717test "using std namespace" {
56945718 try testing.expect(true);
5719}
5720 {#code_end#}
5721 <p>
5722 {#syntax#}usingnamespace{#endsyntax#} can also be used in containers:
5723 </p>
5724 {#code_begin|test|usingnamespace_inside_struct#}
5725test "using namespace inside struct" {
5726 const L = struct {
5727 usingnamespace struct {
5728 pub fn f() void {}
5729 };
5730 };
5731 L.f();
56955732}
56965733 {#code_end#}
56975734 <p>
......@@ -6044,7 +6081,7 @@ test "fibonacci" {
60446081 </p>
60456082
60466083 <p>
6047 In the global scope (outside of any function), all expressions are implicitly
6084 At container level (outside of any function), all expressions are implicitly
60486085 {#syntax#}comptime{#endsyntax#} expressions. This means that we can use functions to
60496086 initialize complex static data. For example:
60506087 </p>
......@@ -8529,7 +8566,7 @@ fn List(comptime T: type) type {
85298566}
85308567 {#code_end#}
85318568 <p>
8532 When {#syntax#}@This(){#endsyntax#} is used at global scope, it returns a reference to the
8569 When {#syntax#}@This(){#endsyntax#} is used at file scope, it returns a reference to the
85338570 struct that corresponds to the current file.
85348571 </p>
85358572 {#header_close#}
......@@ -8744,7 +8781,7 @@ pub fn build(b: *Builder) void {
87448781 {#header_open|Single Threaded Builds#}
87458782 <p>Zig has a compile option <code>--single-threaded</code> which has the following effects:</p>
87468783 <ul>
8747 <li>All {#link|Thread Local Variables#} are treated as {#link|Global Variables#}.</li>
8784 <li>All {#link|Thread Local Variables#} are treated as regular {#link|Container Level Variables#}.</li>
87488785 <li>The overhead of {#link|Async Functions#} becomes equivalent to function call overhead.</li>
87498786 <li>The {#syntax#}@import("builtin").single_threaded{#endsyntax#} becomes {#syntax#}true{#endsyntax#}
87508787 and therefore various userland APIs which read this variable become more efficient.