Skip to main content

Compiler directives

These are keywords that start with # and instruct the compiler to do some actions, checks, or change parameters.

Those directives can be used only at the outermost level (not inside any function definition).


The #include directive allows to include another FunC source code file that will be parsed in place of include.

Syntax is #include "filename.fc";. Files are automatically checked for re-inclusion, and attempts to include a file more than once will be ignored by default, with a warning if the verbosity level is no lower than 2.

If an error happens during the parsing of an included file, additionally, a stack of inclusions is printed with the locations of each included file in the chain.


The #pragma directive is used to provide additional information to the compiler beyond what the language itself conveys.

#pragma version

Version pragma is used to enforce a specific version of FunC compiler when compiling the file.

The version is specified in a semver format, that is, a.b.c, where a is the major version, b is the minor, and c is the patch.

There are several comparison operators available to a developer:

  • a.b.c or =a.b.c—requires exactly the a.b.c version of the compiler
  • >a.b.c—requires the compiler version to be higher than a.b.c,
    • >=a.b.c—requires the compiler version to be higher or equal to a.b.c
  • <a.b.c—requires the compiler version to be lower than a.b.c,
    • <=a.b.c—requires the compiler version to be lower or equal to a.b.c
  • ^a.b.c—requires the major compiler version to be equal to the 'a' part and the minor to be no lower than the 'b' part,
    • ^a.b—requires the major compiler version to be equal to a part and minor be no lower than b part
    • ^a—requires the major compiler version to be no lower than a part

For other comparison operators (=, >, >=, <, <=) short format assumes zeros in omitted parts, that is:

  • >a.b is the same as >a.b.0 (and therefore does NOT match thd a.b.0 version)
  • <=a is the same as <=a.0.0 (and therefore does NOT match the a.0.1 version)
  • ^a.b.0 is NOT the same as ^a.b

For example, ^a.1.2 matches a.1.3 but not a.2.3 or a.1.0, however, ^a.1 matches them all.

This directive may be used multiple times; the compiler version must satisfy all provided conditions.

#pragma not-version

The syntax of this pragma is the same as the version pragma but it fails if the condition is satisfied.

It can be used for blacklisting a specific version known to have problems, for example.

#pragma allow-post-modification

funC v0.4.1

By default it is prohibited to use variable prior to its modification in the same expression. In other words, expression (x, y) = (ds, ds~load_uint(8)) won't compile, while (x, y) = (ds~load_uint(8), ds) is valid.

This rule can be overwritten, by #pragma allow-post-modification, which allow to modify variable after usage in mass assignments and function invocation; as usual sub-expressions will be computed left to right: (x, y) = (ds, ds~load_bits(8)) will result in x containing initial ds; f(ds, ds~load_bits(8)) first argument of f will contain initial ds, and second - 8 bits of ds.

#pragma allow-post-modification works only for code after the pragma.

#pragma compute-asm-ltr

funC v0.4.1

Asm declarations can overwrite order of arguments, for instance in the following expression

idict_set_ref(ds~load_dict(), ds~load_uint(8), ds~load_uint(256), ds~load_ref())

order of parsing will be: load_ref(), load_uint(256), load_dict() and load_uint(8) due to following asm declaration (note asm(value index dict key_len)):

cell idict_set_ref(cell dict, int key_len, int index, cell value) asm(value index dict key_len) "DICTISETREF";

This behavior can be changed to strict left-to-right order of computation via #pragma compute-asm-ltr

As a result in

#pragma compute-asm-ltr
idict_set_ref(ds~load_dict(), ds~load_uint(8), ds~load_uint(256), ds~load_ref());

order of parsing will be load_dict(), load_uint(8), load_uint(256), load_ref() and all asm permutation will happen after computation.

#pragma compute-asm-ltr works only for code after the pragma.