# FunC global variables (https://docs-dmpho5eos-ton-core-docs.vercel.app/llms/languages/func/global-variables/content.md)



<Callout type="note">
  The official smart contract language of TON Blockchain is [Tolk](/llms/tolk/overview/content.md). FunC is now a **legacy** language, with its compiler no longer maintained.

  Learn how to [migrate from FunC to Tolk](/llms/tolk/from-func/tolk-vs-func/content.md). For new smart contract projects, use the [Acton toolchain](/llms/contract-dev/acton/content.md).
</Callout>

## Definition [#definition]

**A global variable** is a variable that can be read and assigned at any function in the entire program, including functions declared in other `.fc` files,
as long as those `.fc` files are [imported](/llms/languages/func/compiler-directives/content.md) after the global
variable [declaration](#declaration). It is possible to use global variables imported from other `.fc` files.

Global variables are useful for remembering values across functions, without the need to pass those values as arguments to every single function in the program.

Under the hood, global variables in FunC are stored inside the tuple of the [`c7` TVM control register](/llms/foundations/whitepapers/tvm/content.md),
with a maximum limit of 31 variables.

## Declaration [#declaration]

Global variables are declared using the `global` keyword, followed by the variable's type and name. For example:

```func
global ((int, int) -> int) op;
```

This defines global variable `op` of type `(int, int) -> int`. In other words, `op` can store a function that receives two arguments and returns an integer.

Here is an example that uses global variable `op`:

```func
global ((int, int) -> int) op;

int check_commutative(int a, int b) {
  return op(a, b) == op(b, a);
}

int add(int a, int b) {
  return a + b;
}

int main() {
  op = add;
  return check_commutative(2, 3);
}
```

The example defines two auxiliary functions: `check_commutative` and `add`, in addition to the program entry point [`main`](/llms/languages/func/special-functions/content.md).
Function `check_commutative` checks if the operator stored in the global variable `op` satisfies the commutative property for the specified inputs `a` and `b`.
Function `add`, adds its two inputs.
Function `main` assigns the addition function `add` to the global variable `op`. Then, it verifies the commutativity of addition for the specific values: `2`, `3`.

In FunC, you can *omit the type* of global variables. In this case, the compiler determines the type based on how the variable is used. Equivalently,
instead of declaring the type, you can use the `var` keyword as a replacement for the type.

For example, in the previous program you can declare the variable `op` as:

```func
global op;
```

or as:

```func
global var op;
```

FunC allows declaring global variable multiple times, as long as all the declarations have the same type.
The declarations can even happen in different `.fc` files.

For example, the following does not compile, because the second declaration changes the type of `A` from `int` to `cell`:

```func
global int A;

int foo() {
  return 0;
}

global cell A;    ;; DOES NOT COMPILE, cell should be int
```

<Callout>
  Global variables do *not* allow initialization during declaration, contrary to local variables, which must be initialized during declaration.
  For example,

  ```func
  global int a = 5;  ;; DOES NOT COMPILE
  ```

  Reading a global variable that has not been assigned, will result in the [`null` value](/llms/languages/func/types/content.md).
</Callout>

<Callout>
  Global variables do not survive after the TVM finishes execution. They are reset every time the
  [TVM initializes](/llms/tvm/initialization/content.md).
  Use permanent storage to remember values between TVM executions by using the [`set_data`](/llms/languages/func/stdlib/content.md) function.

  For example, in the following code, you should **not** expect that global variable `prev_value` will remember the message value
  `msg_value` of the previously received internal message. Because every time the contract receives an internal message,
  the TVM initializes.

  ```func
  global int prev_value;

  () recv_internal(int msg_value, cell in_msg_cell, slice in_msg) {
    ;; ...
    ;; ...
    if (prev_value > 123456) {   ;; prev_value will NOT have the value
      ;; do something            ;; of the previously received message
    }
    prev_value = msg_value;    ;; Use permanent storage instead
  }
  ```
</Callout>

## Multiple declarations [#multiple-declarations]

FunC allows users to declare multiple global variables using a single `global` keyword.

The following example:

```func
global int A;
global cell B;
global C;
```

is equivalent to this:

```func
global int A, cell B, C;
```

## Restrictions on declarations [#restrictions-on-declarations]

A local variable **cannot** have the same name of a previously declared global variable **but only if their types differ**.

The following example does not compile, because the local variable `C` of type `int` has the same name as the global variable `C` of type `cell`,
and `int` and `cell` are different types.

```func
global cell C;

int main() {
  int C = 3; ;; DOES NOT COMPILE
  return C;
}
```

However, if the local variable and the global variable have the same type and the same name, the declaration of the local variable actually means assignment
to the global variable. For example,

```func
global int C;

int main() {
  int C = 3;
  return C;
}
```

In this case, `int C = 3;` is not declaring a new local variable, but instead assigning value `3` to the global variable `C`.
