authorgravatar for rofrol@gmail.comRoman Frołow <rofrol@gmail.com> 2021-06-23 07:45:36+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-07-03 15:22:21-07:00
log9349c9c4b1b964d00241bcc310951bfcd22ee86e
tree32709a0345ac36c266ab41fa872e3fcea74d6f16
parent6caa77ea522ad7e604ac61acf48c2cabdd7926ac

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 {...@@ -258,7 +258,7 @@ pub fn main() !void {
258 <p>258 <p>
259 The code sample begins by adding Zig's Standard Library to the build using the {#link|@import#} builtin function.259 The code sample begins by adding Zig's Standard Library to the build using the {#link|@import#} builtin function.
260 The {#syntax#}@import("std"){#endsyntax#} function call creates a structure to represent the Standard Library.260 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 a261 The code then {#link|declares|Container level Variables#} a
262 {#link|constant identifier|Assignment#}, named <code>std</code>, for easy access to262 {#link|constant identifier|Assignment#}, named <code>std</code>, for easy access to
263 <a href="https://github.com/ziglang/zig/wiki/FAQ#where-is-the-documentation-for-the-zig-standard-library">Zig's standard library</a>.263 <a href="https://github.com/ziglang/zig/wiki/FAQ#where-is-the-documentation-for-the-zig-standard-library">Zig's standard library</a>.
264 </p>264 </p>
...@@ -802,7 +802,7 @@ const hello_world_in_c =...@@ -802,7 +802,7 @@ const hello_world_in_c =
802const x = 1234;802const x = 1234;
803803
804fn foo() void {804fn foo() void {
805 // It works at global scope as well as inside functions.805 // It works at file scope as well as inside functions.
806 const y = 5678;806 const y = 5678;
807807
808 // Once assigned, an identifier cannot be changed.808 // Once assigned, an identifier cannot be changed.
...@@ -872,18 +872,18 @@ test "init with undefined" {...@@ -872,18 +872,18 @@ test "init with undefined" {
872 {#syntax#}var{#endsyntax#} when declaring a variable. This causes less work for both872 {#syntax#}var{#endsyntax#} when declaring a variable. This causes less work for both
873 humans and computers to do when reading code, and creates more optimization opportunities.873 humans and computers to do when reading code, and creates more optimization opportunities.
874 </p>874 </p>
875 {#header_open|Global Variables#}875 {#header_open|Container Level Variables#}
876 <p>876 <p>
877 Global variables are considered to be a top level declaration, which means that they are877 Container level variables have static lifetime and are order-independent and lazily analyzed.
878 order-independent and lazily analyzed. The initialization value of global variables is implicitly878 The initialization value of container level variables is implicitly
879 {#link|comptime#}. If a global variable is {#syntax#}const{#endsyntax#} then its value is879 {#link|comptime#}. If a container level variable is {#syntax#}const{#endsyntax#} then its value is
880 {#syntax#}comptime{#endsyntax#}-known, otherwise it is runtime-known.880 {#syntax#}comptime{#endsyntax#}-known, otherwise it is runtime-known.
881 </p>881 </p>
882 {#code_begin|test|global_variables#}882 {#code_begin|test|container_level_variables#}
883var y: i32 = add(10, x);883var y: i32 = add(10, x);
884const x: i32 = add(12, 34);884const x: i32 = add(12, 34);
885885
886test "global variables" {886test "container level variables" {
887 try expect(x == 46);887 try expect(x == 46);
888 try expect(y == 56);888 try expect(y == 56);
889}889}
...@@ -896,27 +896,51 @@ const std = @import("std");...@@ -896,27 +896,51 @@ const std = @import("std");
896const expect = std.testing.expect;896const expect = std.testing.expect;
897 {#code_end#}897 {#code_end#}
898 <p>898 <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#}:
900 </p>900 </p>
901 {#code_begin|test|namespaced_global#}901 {#code_begin|test|namespaced_container_level_variable#}
902const std = @import("std");902const std = @import("std");
903const expect = std.testing.expect;903const expect = std.testing.expect;
904904
905test "namespaced global variable" {905test "namespaced container level variable" {
906 try expect(foo() == 1235);906 try expect(foo() == 1235);
907 try expect(foo() == 1236);907 try expect(foo() == 1236);
908}908}
909909
910const S = struct {
911 var x: i32 = 1234;
912};
913
910fn foo() i32 {914fn foo() i32 {
911 const S = struct {
912 var x: i32 = 1234;
913 };
914 S.x += 1;915 S.x += 1;
915 return S.x;916 return S.x;
916}917}
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 }
917 {#code_end#}941 {#code_end#}
918 <p>942 <p>
919 The {#syntax#}extern{#endsyntax#} keyword can be used to link against a variable that is exported943 The {#syntax#}extern{#endsyntax#} keyword or {#link|@extern#} builtin function can be used to link against a variable that is exported
920 from another object. The {#syntax#}export{#endsyntax#} keyword or {#link|@export#} builtin function944 from another object. The {#syntax#}export{#endsyntax#} keyword or {#link|@export#} builtin function
921 can be used to make a variable available to other objects at link time. In both cases,945 can be used to make a variable available to other objects at link time. In both cases,
922 the type of the variable must be C ABI compatible.946 the type of the variable must be C ABI compatible.
...@@ -948,7 +972,7 @@ fn testTls(context: void) void {...@@ -948,7 +972,7 @@ fn testTls(context: void) void {
948}972}
949 {#code_end#}973 {#code_end#}
950 <p>974 <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#}.
952 </p>976 </p>
953 <p>977 <p>
954 Thread local variables may not be {#syntax#}const{#endsyntax#}.978 Thread local variables may not be {#syntax#}const{#endsyntax#}.
...@@ -2467,7 +2491,7 @@ test "dot product" {...@@ -2467,7 +2491,7 @@ test "dot product" {
2467 try expect(Vec3.dot(v1, v2) == 0.0);2491 try expect(Vec3.dot(v1, v2) == 0.0);
2468}2492}
24692493
2470// Structs can have global declarations.2494// Structs can have declarations.
2471// Structs can have 0 fields.2495// Structs can have 0 fields.
2472const Empty = struct {2496const Empty = struct {
2473 pub const PI = 3.14;2497 pub const PI = 3.14;
...@@ -5684,7 +5708,7 @@ test "@intToPtr for pointer to zero bit type" {...@@ -5684,7 +5708,7 @@ test "@intToPtr for pointer to zero bit type" {
56845708
5685 {#header_open|usingnamespace#}5709 {#header_open|usingnamespace#}
5686 <p>5710 <p>
5687 {#syntax#}usingnamespace{#endsyntax#} is a top level declaration that imports all the public declarations of5711 {#syntax#}usingnamespace{#endsyntax#} is a declaration that imports all the public declarations of
5688 the operand, which must be a {#link|struct#}, {#link|union#}, or {#link|enum#}, into the current scope:5712 the operand, which must be a {#link|struct#}, {#link|union#}, or {#link|enum#}, into the current scope:
5689 </p>5713 </p>
5690 {#code_begin|test|usingnamespace#}5714 {#code_begin|test|usingnamespace#}
...@@ -5692,6 +5716,19 @@ usingnamespace @import("std");...@@ -5692,6 +5716,19 @@ usingnamespace @import("std");
56925716
5693test "using std namespace" {5717test "using std namespace" {
5694 try testing.expect(true);5718 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();
5695}5732}
5696 {#code_end#}5733 {#code_end#}
5697 <p>5734 <p>
...@@ -6044,7 +6081,7 @@ test "fibonacci" {...@@ -6044,7 +6081,7 @@ test "fibonacci" {
6044 </p>6081 </p>
60456082
6046 <p>6083 <p>
6047 In the global scope (outside of any function), all expressions are implicitly6084 At container level (outside of any function), all expressions are implicitly
6048 {#syntax#}comptime{#endsyntax#} expressions. This means that we can use functions to6085 {#syntax#}comptime{#endsyntax#} expressions. This means that we can use functions to
6049 initialize complex static data. For example:6086 initialize complex static data. For example:
6050 </p>6087 </p>
...@@ -8520,7 +8557,7 @@ fn List(comptime T: type) type {...@@ -8520,7 +8557,7 @@ fn List(comptime T: type) type {
8520}8557}
8521 {#code_end#}8558 {#code_end#}
8522 <p>8559 <p>
8523 When {#syntax#}@This(){#endsyntax#} is used at global scope, it returns a reference to the8560 When {#syntax#}@This(){#endsyntax#} is used at file scope, it returns a reference to the
8524 struct that corresponds to the current file.8561 struct that corresponds to the current file.
8525 </p>8562 </p>
8526 {#header_close#}8563 {#header_close#}
...@@ -8735,7 +8772,7 @@ pub fn build(b: *Builder) void {...@@ -8735,7 +8772,7 @@ pub fn build(b: *Builder) void {
8735 {#header_open|Single Threaded Builds#}8772 {#header_open|Single Threaded Builds#}
8736 <p>Zig has a compile option <code>--single-threaded</code> which has the following effects:</p>8773 <p>Zig has a compile option <code>--single-threaded</code> which has the following effects:</p>
8737 <ul>8774 <ul>
8738 <li>All {#link|Thread Local Variables#} are treated as {#link|Global Variables#}.</li>8775 <li>All {#link|Thread Local Variables#} are treated as regular {#link|Container Level Variables#}.</li>
8739 <li>The overhead of {#link|Async Functions#} becomes equivalent to function call overhead.</li>8776 <li>The overhead of {#link|Async Functions#} becomes equivalent to function call overhead.</li>
8740 <li>The {#syntax#}@import("builtin").single_threaded{#endsyntax#} becomes {#syntax#}true{#endsyntax#}8777 <li>The {#syntax#}@import("builtin").single_threaded{#endsyntax#} becomes {#syntax#}true{#endsyntax#}
8741 and therefore various userland APIs which read this variable become more efficient.8778 and therefore various userland APIs which read this variable become more efficient.