|
1 | 1 | --- |
2 | 2 | title: Compiler Directives |
3 | 3 | description: Learn about F# language conditional compilation directives, line directives, and warn directives. |
4 | | -ms.date: 12/10/2018 |
| 4 | +ms.date: 10/21/2025 |
5 | 5 | f1_keywords: |
6 | 6 | - "#endif_FS" |
| 7 | +ai-usage: ai-assisted |
7 | 8 | --- |
8 | 9 | # Compiler Directives |
9 | 10 |
|
@@ -53,6 +54,58 @@ There is no `#define` compiler directive in F#. You must use the compiler option |
53 | 54 |
|
54 | 55 | Conditional compilation directives can be nested. Indentation is not significant for compiler directives. |
55 | 56 |
|
| 57 | +## Predefined symbols |
| 58 | + |
| 59 | +The F# compiler and build system automatically define several symbols that can be used for conditional compilation. |
| 60 | + |
| 61 | +### Build configuration symbols |
| 62 | + |
| 63 | +The following symbols are defined based on your build configuration: |
| 64 | + |
| 65 | +- `DEBUG`: Defined when compiling in Debug mode. In the project system, the `DEBUG` symbol is automatically defined in the Debug configuration, but not in the Release configuration. This symbol is commonly used with assertions and diagnostic code. For more information, see [Assertions](assertions.md). |
| 66 | +- `TRACE`: Defined for builds that enable tracing. Like `DEBUG`, this symbol is typically defined in Debug configurations but can also be enabled in Release configurations. |
| 67 | + |
| 68 | +You can override these values using the [`-define` compiler option](compiler-options.md) or project settings. |
| 69 | + |
| 70 | +### Compilation mode symbols |
| 71 | + |
| 72 | +The following symbols distinguish between different compilation modes: |
| 73 | + |
| 74 | +- `COMPILED`: Defined when compiling code with the F# compiler. This symbol is useful when you need code to behave differently in compiled assemblies versus F# Interactive sessions. |
| 75 | +- `INTERACTIVE`: Defined when compiling or executing code in F# Interactive (`dotnet fsi`), including both interactive sessions and script execution. This allows you to write code that works differently when running interactively. |
| 76 | + |
| 77 | +For more information about using these symbols in scripts, see [Interactive Programming with F#](../tools/fsharp-interactive/index.md). |
| 78 | + |
| 79 | +Example: |
| 80 | + |
| 81 | +```fsharp |
| 82 | +#if INTERACTIVE |
| 83 | +// Code specific to F# Interactive |
| 84 | +#r "nuget: Newtonsoft.Json" |
| 85 | +#endif |
| 86 | +
|
| 87 | +#if COMPILED |
| 88 | +// Code specific to compiled assemblies |
| 89 | +open System.Configuration |
| 90 | +#endif |
| 91 | +``` |
| 92 | + |
| 93 | +### Target framework symbols |
| 94 | + |
| 95 | +The build system also defines preprocessor symbols for different target frameworks in SDK-style projects. These symbols are useful when creating libraries or applications that target multiple .NET versions. |
| 96 | + |
| 97 | +[!INCLUDE [Preprocessor symbols](~/includes/preprocessor-symbols.md)] |
| 98 | + |
| 99 | +For example, you can use these symbols to conditionally compile code based on the target framework: |
| 100 | + |
| 101 | +```fsharp |
| 102 | +#if NET6_0_OR_GREATER |
| 103 | +// Use .NET 6+ specific APIs |
| 104 | +#else |
| 105 | +// Use alternative implementation for older frameworks |
| 106 | +#endif |
| 107 | +``` |
| 108 | + |
56 | 109 | ## NULLABLE directive |
57 | 110 |
|
58 | 111 | Starting with F# 9, you can enable nullable reference types in the project: |
|
0 commit comments