]>
Commit | Line | Data |
---|---|---|
ea8adc8c XL |
1 | # Static items |
2 | ||
8faf50e0 XL |
3 | > **<sup>Syntax</sup>**\ |
4 | > _StaticItem_ :\ | |
ff7c6d11 XL |
5 | > `static` `mut`<sup>?</sup> [IDENTIFIER] `:` [_Type_] |
6 | > `=` [_Expression_] `;` | |
7 | ||
8 | A *static item* is similar to a [constant], except that it represents a precise | |
83c7162d XL |
9 | memory location in the program. All references to the static refer to the same |
10 | memory location. Static items have the `static` lifetime, which outlives all | |
3dfed10e XL |
11 | other lifetimes in a Rust program. Static items do not call [`drop`] at the |
12 | end of the program. | |
13 | ||
14 | The static initializer is a [constant expression] evaluated at compile time. | |
15 | Static initializers may refer to other statics. | |
16 | ||
17 | Non-`mut` static items that contain a type that is not [interior mutable] may | |
18 | be placed in read-only memory. | |
ea8adc8c | 19 | |
ea8adc8c XL |
20 | All access to a static is safe, but there are a number of restrictions on |
21 | statics: | |
22 | ||
ff7c6d11 | 23 | * The type must have the `Sync` trait bound to allow thread-safe access. |
ea8adc8c XL |
24 | * Constants cannot refer to statics. |
25 | ||
ea8adc8c XL |
26 | ## Mutable statics |
27 | ||
28 | If a static item is declared with the `mut` keyword, then it is allowed to be | |
29 | modified by the program. One of Rust's goals is to make concurrency bugs hard | |
30 | to run into, and this is obviously a very large source of race conditions or | |
31 | other bugs. For this reason, an `unsafe` block is required when either reading | |
32 | or writing a mutable static variable. Care should be taken to ensure that | |
33 | modifications to a mutable static are safe with respect to other threads | |
34 | running in the same process. | |
35 | ||
36 | Mutable statics are still very useful, however. They can be used with C | |
83c7162d | 37 | libraries and can also be bound from C libraries in an `extern` block. |
ea8adc8c XL |
38 | |
39 | ```rust | |
40 | # fn atomic_add(_: &mut u32, _: u32) -> u32 { 2 } | |
41 | ||
42 | static mut LEVELS: u32 = 0; | |
43 | ||
44 | // This violates the idea of no shared state, and this doesn't internally | |
45 | // protect against races, so this function is `unsafe` | |
46 | unsafe fn bump_levels_unsafe1() -> u32 { | |
47 | let ret = LEVELS; | |
48 | LEVELS += 1; | |
49 | return ret; | |
50 | } | |
51 | ||
52 | // Assuming that we have an atomic_add function which returns the old value, | |
53 | // this function is "safe" but the meaning of the return value may not be what | |
54 | // callers expect, so it's still marked as `unsafe` | |
55 | unsafe fn bump_levels_unsafe2() -> u32 { | |
56 | return atomic_add(&mut LEVELS, 1); | |
57 | } | |
58 | ``` | |
59 | ||
60 | Mutable statics have the same restrictions as normal statics, except that the | |
ff7c6d11 | 61 | type does not have to implement the `Sync` trait. |
ea8adc8c | 62 | |
ff7c6d11 XL |
63 | ## Using Statics or Consts |
64 | ||
83c7162d | 65 | It can be confusing whether or not you should use a constant item or a static |
ff7c6d11 XL |
66 | item. Constants should, in general, be preferred over statics unless one of the |
67 | following are true: | |
68 | ||
69 | * Large amounts of data are being stored | |
83c7162d | 70 | * The single-address property of statics is required. |
ff7c6d11 XL |
71 | * Interior mutability is required. |
72 | ||
416331ca XL |
73 | [constant]: constant-items.md |
74 | [`drop`]: ../destructors.md | |
75 | [constant expression]: ../const_eval.md#constant-expressions | |
76 | [interior mutable]: ../interior-mutability.md | |
77 | [IDENTIFIER]: ../identifiers.md | |
78 | [_Type_]: ../types.md#type-expressions | |
79 | [_Expression_]: ../expressions.md |