> ## Documentation Index
> Fetch the complete documentation index at: https://companyname-a7d5b98e-security-edits.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# FunC compiler directives

export const Image = ({src, darkSrc, alt = '', darkAlt, href, target, height = 342, width = 608, noZoom = false, center = false}) => {
  const isSVG = src.match(/\.svg(?:[#?].*?)?$/i) !== null;
  const shouldInvert = isSVG && !darkSrc;
  const shouldCreateLink = href !== undefined;
  const minPx = 9;
  const maxPx = 608;
  const expectedPx = `a number or a string with a number that is greater than ${minPx - 1} and less than or equal to ${maxPx}`;
  const createInvalidPropCallout = (title, received, expected) => {
    return <Danger>
        <span className="font-bold">
          Invalid <code>{title.toString()}</code> passed!
        </span>
        <br />
        <span className="font-bold">Received: </span>
        {received.toString()}
        <br />
        <span className="font-bold">Expected: </span>
        {expected.toString()}
        {}
      </Danger>;
  };
  const checkValidDimensionValue = value => {
    switch (typeof value) {
      case "string":
      case "number":
        const num = Number(value);
        return Number.isSafeInteger(num) && num >= minPx && num <= maxPx;
      default:
        return false;
    }
  };
  let callouts = [];
  if (height && !checkValidDimensionValue(height)) {
    callouts.push(createInvalidPropCallout("height", height, expectedPx));
  }
  if (width && !checkValidDimensionValue(width)) {
    callouts.push(createInvalidPropCallout("width", width, expectedPx));
  }
  if (callouts.length !== 0) {
    return callouts;
  }
  const heightPx = Number(height);
  const widthPx = Number(width);
  const shouldCenter = center === "true" || center === true ? true : false;
  const shouldNotZoom = noZoom === "true" || noZoom === true ? true : false;
  const images = <>
      <img className="block dark:hidden" src={src} alt={alt} {...height && ({
    height: heightPx
  })} {...width && ({
    width: widthPx
  })} {...(shouldCreateLink || shouldInvert || shouldNotZoom) && ({
    noZoom: "true"
  })} />
      <img className={`hidden dark:block ${shouldInvert ? "invert" : ""}`} src={darkSrc ?? src} alt={darkAlt ?? alt} {...height && ({
    height: heightPx
  })} {...width && ({
    width: widthPx
  })} {...(shouldCreateLink || shouldInvert || shouldNotZoom) && ({
    noZoom: "true"
  })} />
    </>;
  if (shouldCreateLink) {
    if (shouldCenter) {
      return <div style={{
        display: "flex",
        justifyContent: "center"
      }}>
          <a href={href} target={target ?? "_self"}>
            {images}
          </a>
        </div>;
    }
    return <a href={href} target={target ?? "_self"}>
        {images}
      </a>;
  }
  if (shouldCenter) {
    return <div style={{
      display: "flex",
      justifyContent: "center"
    }}>{images}</div>;
  }
  return images;
};

export const Aside = ({type = "note", title = "", icon = "", iconType = "regular", children}) => {
  const asideVariants = ["note", "tip", "caution", "danger"];
  const asideComponents = {
    note: {
      outerStyle: "border-sky-500/20 bg-sky-50/50 dark:border-sky-500/30 dark:bg-sky-500/10",
      innerStyle: "text-sky-900 dark:text-sky-200",
      calloutType: "note",
      icon: <svg width="14" height="14" viewBox="0 0 14 14" fill="currentColor" xmlns="http://www.w3.org/2000/svg" className="w-4 h-4 text-sky-500" aria-label="Note">
          <path fill-rule="evenodd" clip-rule="evenodd" d="M7 1.3C10.14 1.3 12.7 3.86 12.7 7C12.7 10.14 10.14 12.7 7 12.7C5.48908 12.6974 4.0408 12.096 2.97241 11.0276C1.90403 9.9592 1.30264 8.51092 1.3 7C1.3 3.86 3.86 1.3 7 1.3ZM7 0C3.14 0 0 3.14 0 7C0 10.86 3.14 14 7 14C10.86 14 14 10.86 14 7C14 3.14 10.86 0 7 0ZM8 3H6V8H8V3ZM8 9H6V11H8V9Z"></path>
        </svg>
    },
    tip: {
      outerStyle: "border-emerald-500/20 bg-emerald-50/50 dark:border-emerald-500/30 dark:bg-emerald-500/10",
      innerStyle: "text-emerald-900 dark:text-emerald-200",
      calloutType: "tip",
      icon: <svg width="11" height="14" viewBox="0 0 11 14" fill="currentColor" xmlns="http://www.w3.org/2000/svg" className="text-emerald-600 dark:text-emerald-400/80 w-3.5 h-auto" aria-label="Tip">
          <path d="M3.12794 12.4232C3.12794 12.5954 3.1776 12.7634 3.27244 12.907L3.74114 13.6095C3.88471 13.8248 4.21067 14 4.46964 14H6.15606C6.41415 14 6.74017 13.825 6.88373 13.6095L7.3508 12.9073C7.43114 12.7859 7.49705 12.569 7.49705 12.4232L7.50055 11.3513H3.12521L3.12794 12.4232ZM5.31288 0C2.52414 0.00875889 0.5 2.26889 0.5 4.78826C0.5 6.00188 0.949566 7.10829 1.69119 7.95492C2.14321 8.47011 2.84901 9.54727 3.11919 10.4557C3.12005 10.4625 3.12175 10.4698 3.12261 10.4771H7.50342C7.50427 10.4698 7.50598 10.463 7.50684 10.4557C7.77688 9.54727 8.48281 8.47011 8.93484 7.95492C9.67728 7.13181 10.1258 6.02703 10.1258 4.78826C10.1258 2.15486 7.9709 0.000106649 5.31288 0ZM7.94902 7.11267C7.52078 7.60079 6.99082 8.37878 6.6077 9.18794H4.02051C3.63739 8.37878 3.10743 7.60079 2.67947 7.11294C2.11997 6.47551 1.8126 5.63599 1.8126 4.78826C1.8126 3.09829 3.12794 1.31944 5.28827 1.3126C7.2435 1.3126 8.81315 2.88226 8.81315 4.78826C8.81315 5.63599 8.50688 6.47551 7.94902 7.11267ZM4.87534 2.18767C3.66939 2.18767 2.68767 3.16939 2.68767 4.37534C2.68767 4.61719 2.88336 4.81288 3.12521 4.81288C3.36705 4.81288 3.56274 4.61599 3.56274 4.37534C3.56274 3.6515 4.1515 3.06274 4.87534 3.06274C5.11719 3.06274 5.31288 2.86727 5.31288 2.62548C5.31288 2.38369 5.11599 2.18767 4.87534 2.18767Z"></path>
        </svg>
    },
    caution: {
      outerStyle: "border-amber-500/20 bg-amber-50/50 dark:border-amber-500/30 dark:bg-amber-500/10",
      innerStyle: "text-amber-900 dark:text-amber-200",
      calloutType: "warning",
      icon: <svg className="flex-none w-5 h-5 text-amber-400 dark:text-amber-300/80" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" aria-label="Warning">
          <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path>
        </svg>
    },
    danger: {
      outerStyle: "border-red-500/20 bg-red-50/50 dark:border-red-500/30 dark:bg-red-500/10",
      innerStyle: "text-red-900 dark:text-red-200",
      calloutType: "danger",
      icon: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor" className="text-red-600 dark:text-red-400/80 w-4 h-4" aria-label="Danger">
          <path d="M17.1 292c-12.9-22.3-12.9-49.7 0-72L105.4 67.1c12.9-22.3 36.6-36 62.4-36l176.6 0c25.7 0 49.5 13.7 62.4 36L494.9 220c12.9 22.3 12.9 49.7 0 72L406.6 444.9c-12.9 22.3-36.6 36-62.4 36l-176.6 0c-25.7 0-49.5-13.7-62.4-36L17.1 292zm41.6-48c-4.3 7.4-4.3 16.6 0 24l88.3 152.9c4.3 7.4 12.2 12 20.8 12l176.6 0c8.6 0 16.5-4.6 20.8-12L453.4 268c4.3-7.4 4.3-16.6 0-24L365.1 91.1c-4.3-7.4-12.2-12-20.8-12l-176.6 0c-8.6 0-16.5 4.6-20.8 12L58.6 244zM256 128c13.3 0 24 10.7 24 24l0 112c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-112c0-13.3 10.7-24 24-24zM224 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z"></path>
        </svg>
    }
  };
  let variant = type;
  let gotInvalidVariant = false;
  if (!asideVariants.includes(type)) {
    gotInvalidVariant = true;
    variant = "danger";
  }
  const iconVariants = ["regular", "solid", "light", "thin", "sharp-solid", "duotone", "brands"];
  if (!iconVariants.includes(iconType)) {
    iconType = "regular";
  }
  return <>
      <div className={`callout my-4 px-5 py-4 overflow-hidden rounded-2xl flex gap-3 border ${asideComponents[variant].outerStyle}`} data-callout-type={asideComponents[variant].calloutType}>
        <div className="mt-0.5 w-4" data-component-part="callout-icon">
          {}
          {icon === "" ? asideComponents[variant].icon : <Icon icon={icon} iconType={iconType} size={14} />}
        </div>
        <div className={`text-sm prose min-w-0 w-full ${asideComponents[variant].innerStyle}`} data-component-part="callout-content">
          {gotInvalidVariant ? <p>
              <span className="font-bold">
                Invalid <code>type</code> passed!
              </span>
              <br />
              <span className="font-bold">Received: </span>
              {type}
              <br />
              <span className="font-bold">Expected one of: </span>
              {asideVariants.join(", ")}
            </p> : <>
              {title && <p className="font-bold">{title}</p>}
              {children}
            </>}
        </div>
      </div>
    </>;
};

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

  FunC pages will be moved down in the sidebar in mid-April 2026. Here is the preview of a possible future placement, right between "Blockchain foundations" and "Contribute" sections:

  <Image src="/resources/images/tmp-func-fift-light.png" darkSrc="/resources/images/tmp-func-fift-dark.png" alt="Preview of a possible future placement of FunC and Fift languages in the sidebar." width={294} height={190} noZoom={true} />

  Learn how to [migrate from FunC to Tolk](/tolk/from-func/tolk-vs-func).
</Aside>

Compiler directives are keywords that begin with `#`, instructing the compiler to perform specific actions, enforce checks, or modify parameters.

These directives can only be used at the outermost level of a source file and cannot be placed inside function definitions.

## `#include`

The `#include` directive enables the inclusion of another FunC source file parsed in place of the directive.

**Syntax:**

```func theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
#include "<path_to_filename>";
```

where `<path_to_filename>` is the path to the FunC source file to include.

Files are automatically checked for multiple inclusions.
By default, the compiler will ignore redundant inclusions if the same file is included more than once.
This also applies to inclusions along a path of nested inclusions.
A warning will be issued if the verbosity level is 2 or higher.

For example, suppose that `main.fc` contains the `main` function. Suppose also that `main.fc` includes a file `A.fc`, which in turn includes a file `B.fc`,
which in turn includes `main.fc`. When `main.fc` is compiled, the inclusion of `main.fc` in `B.fc` will be ignored.

If an error occurs while parsing an included file, the compiler displays an inclusion stack, showing the locations of each file in the inclusion chain.

## `#pragma`

The `#pragma` directive provides additional information to the compiler beyond what the language conveys.

### `#pragma` version

The `#pragma` version directive enforces using a specific FunC compiler version when compiling the file.

**Syntax:**

```func theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
#pragma version <op><sem_version>;
```

where `<op>` is an optional [version operator](#operators) that allows to specify a constraint, and `<sem_version>` is specified
in [**semantic versioning (semver)** format](https://en.wikipedia.org/wiki/Software_versioning): *a.b.c*, where:

* *a* is the major version
* *b* is the minor version
* *c* is the patch version

Example:

```func theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
#pragma version 2.3.4;
#pragma version >2.3.4;
```

The first example does not use an operator and it means that the compiler must have exactly version `2.3.4`.
The second uses the greater than operator `>`, and it means that the compiler must have a version greater
than `2.3.4` (see [precedence](#equality-and-precedence) and [operators](#operators) below for details).

#### Equality and precedence

Two versions are **equal** if their respective major, minor, and patch numbers are equal. Two versions are **not equal** if at least one of those numbers differ.

Example:

* *1.2.3* is equal to *1.2.3*
* *3.4.5* is not equal to *3.1.5*

**Precedence** of two versions *a.b.c* and *d.e.f* is determined the following way:

* If *a* is smaller than *d*, then *a.b.c* precedes *d.e.f*
* If *a* is equal to *d*, and *b* is smaller than *e*, then *a.b.c* precedes *d.e.f*
* If *a* is equal to *d*, and *b* is equal to *e*, and *c* is smaller than *f*, then *a.b.c* precedes *d.e.f*

If *a.b.c* precedes *d.e.f*, then it is said that *a.b.c* is smaller than *d.e.f*, or equivalently, that *d.e.f* is greater than *a.b.c*.

Example:

* *1.0.0* precedes *2.0.0*. Equivalently: *1.0.0* is smaller than *2.0.0* or *2.0.0* is greater than *1.0.0*.
* *2.0.0* precedes *2.1.0*. Equivalently: *2.0.0* is smaller than *2.1.0* or *2.1.0* is greater than *2.0.0*.
* *2.1.0* precedes *2.1.1*. Equivalently: *2.1.0* is smaller than *2.1.1* or *2.1.1* is greater than *2.1.0*.

#### Operators

Developers can specify version constraints using the following operators:

* *a.b.c* or *=a.b.c* - Requires **exactly** version *a.b.c* of the compiler
* *>a.b.c* - Requires the compiler version to be **greater** than *a.b.c.*
* *>=a.b.c* - Requires the compiler version to be **greater** than or **equal** to *a.b.c*
* *\<a.b.c* - Requires the compiler version to be **less** than *a.b.c*
* *\<=a.b.c* - Requires the compiler version to be **less** than or **equal** to *a.b.c*
* *^a.b.c* - Requires the major part of the compiler version to be **equal** to the *a* part, the minor to be **equal** to the *b* part, and the patch to be **no lower** than the *c* part
* *^a.b* - Requires the major compiler version to be **equal** to the *a* part and the minor to be **no lower** than the *b* part
* *^a* - Requires the major compiler version to be **no lower** than the *a* part

For the comparison operators *=*, *>*, *>=*, *\<*, *\<=*, omitted parts default to zero.
For example:

* *>a.b* is equivalent to *>a.b.0*
* *\<=a* is equivalent to *\<=a.0.0*

For the operator ^, omitted parts do **not** default to zero. For example:

* *^a.b* is not equivalent to *^a.b.0*
* *^a* is not equivalent to *^a.0.0*

Here are some examples of constraints:

* *^5.1.2* matches compiler version *5.1.3* because patch `3` is no lower than patch `2`.
* *^5.1.2* does not match compiler version *5.2.3* because minor `2` does not equal minor `1`.
* *^5.1.2* does not match compiler version *5.1.1* because patch `1` is lower than patch `2`.
* *^5.1* matches compiler version *5.1.3* because minor `1` is no lower than minor `1`.
* *^5.1* matches compiler version *5.2.3* because minor `2` is no lower than minor `1`.
* *^5.1* matches compiler version *5.1.0* because minor `1` is no lower than minor `1`.
* *^5.1* does not match compiler version *5.0.2* because minor `0` is lower than minor `1`.
* *^5* matches compiler version *5.1.0* because major `5` is no lower than major `5`.
* *^5* does not match compiler version *4.1.0* because major `4` is lower than major `5`.
* *>5.1.2* matches compiler version *5.1.3* because patch `3` is bigger than patch `2`.
* *>5.1.2* matches compiler version *5.2.0* because minor `2` is bigger than minor `1`.
* *>5.1.2* matches compiler version *6.0.0* because major `6` is bigger than major `5`.
* *=5.1.2* does not match compiler version *5.2.2* because minor `2` is not equal to minor `1`.

<Aside>
  The `#pragma` version directive can be used multiple times, and the compiler must satisfy all specified constraints.
</Aside>

### `#pragma not-version`

The `#pragma not-version` is similar to `#pragma version`, but it fails if the specified condition is met.

**Syntax:**

```func theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
#pragma not-version <op><sem_version>;
```

where `<op>` is an optional [version operator](#operators) that allows to specify a constraint, and `<sem_version>` is identical as
in [`#pragma version`](#%23pragma-version).

This directive is useful for blocking specific compiler versions known to have issues.

Here are some examples:

```func theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
#pragma not-version >2.1.3;
#pragma not-version ^3.4;
#pragma not-version 1.2.3;
```

In the first example, `not-version >2.1.3` matches any compiler version that is *not* bigger than *2.1.3*, like *2.1.2*, *2.0.5* and even *2.1.3* itself.

In the second example, `not-version ^3.4` matches any compiler version that does *not* match *^3.4*, like *3.3.1*, *4.4.0*, and *3.3.9*

In the third example, `not-version 1.2.3` matches any compiler version different from *1.2.3*.

### `#pragma allow-post-modification`

*Introduced in FunC v0.4.1*

In Func, using a variable before it is modified within the same [expression](/languages/func/expressions) is prohibited by default.

For example, the following code will **not** compile, because `ds` is used before it is modified in `ds~load_uint(8)`.
See [modifying notation](/languages/func/expressions#modifying-notation) for more details on using symbol `~`.

```func theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
(x, y) = (ds, ds~load_uint(8));
```

However, this version is **valid**, since `ds` is used after it is modified:

```func theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
(x, y) = (ds~load_uint(8), ds)
```

To override this restriction, use `#pragma allow-post-modification`.
This allows variables to be modified after usage in mass assignments and function calls while sub-expressions are still computed **left to right**.

In the following example, `x` will contain the initial value of `ds`, while `y` the modified value of `ds`:

```func theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
#pragma allow-post-modification
(x, y) = (ds, ds~load_bits(8));
```

<Aside>
  `#pragma allow-post-modification` works only for code after the pragma.
</Aside>

### `#pragma compute-asm-ltr`

*Introduced in FunC v0.4.1*

`asm` declarations can override the order of argument evaluation. For example, in the following expression:

```func theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
idict_set_ref(ds~load_dict(), ds~load_uint(8), ds~load_uint(256), ds~load_ref())
```

The evaluation order of the call arguments is:

1. `load_ref()`
2. `load_uint(256)`
3. `load_dict()`
4. `load_uint(8)`

This happens due to the corresponding `asm` declaration:

```func theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
cell idict_set_ref(cell dict, int key_len, int index, cell value) asm(value index dict key_len) "DICTISETREF";
```

Here, the `asm(value index dict key_len)` notation dictates a [rearrangement of arguments](/languages/func/asm-functions#rearranging-stack-entries).

To ensure strict left-to-right computation order of the arguments, use `#pragma compute-asm-ltr`.
With this directive enabled, the same function call:

```func theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
#pragma compute-asm-ltr
;; ...
idict_set_ref(ds~load_dict(), ds~load_uint(8), ds~load_uint(256), ds~load_ref());
```

will evaluate its arguments in the following order:

1. `load_dict()`
2. `load_uint(8)`
3. `load_uint(256)`
4. `load_ref()`

and only *after* the evaluation of all these arguments, the `asm` rearrangement will occur.

<Aside>
  `#pragma compute-asm-ltr` works only for code after the pragma.
</Aside>
