Skip to content

Commit 3b21ced

Browse files
Martin521T-Gro
andauthored
update compiler directives page of FSharp reference (#47130)
* update for RFC FS-1146 (scoped nowarn) and for extended if grammar * Update docs/fsharp/language-reference/compiler-directives.md Co-authored-by: Tomas Grosup <[email protected]> * removed empty line (for the linter) * more details on warn directives * fixed link * fixed the fix * sorry, yet another correction --------- Co-authored-by: Tomas Grosup <[email protected]>
1 parent 8a46fac commit 3b21ced

File tree

1 file changed

+62
-25
lines changed

1 file changed

+62
-25
lines changed

docs/fsharp/language-reference/compiler-directives.md

Lines changed: 62 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,58 @@
11
---
22
title: Compiler Directives
3-
description: Learn about F# language preprocessor directives, conditional compilation directives, line directives, and compiler directives.
3+
description: Learn about F# language conditional compilation directives, line directives, and warn directives.
44
ms.date: 12/10/2018
55
f1_keywords:
66
- "#endif_FS"
77
---
88
# Compiler Directives
99

10-
This topic describes processor directives and compiler directives.
10+
This topic describes compiler directives, for F# Interactive (`dotnet fsi`) directives, see [Interactive Programming with F#](../tools/fsharp-interactive/index.md).
1111

12-
For F# Interactive (`dotnet fsi`) directives, see [Interactive Programming with F#](../tools/fsharp-interactive/index.md).
12+
A compiler directive is prefixed with the # symbol and appears on a line by itself.
1313

14-
## Preprocessor Directives
15-
16-
A preprocessor directive is prefixed with the # symbol and appears on a line by itself. It is interpreted by the preprocessor, which runs before the compiler itself.
17-
18-
The following table lists the preprocessor directives that are available in F#.
14+
The following table lists the compiler directives that are available in F#.
1915

2016
|Directive|Description|
2117
|---------|-----------|
22-
|`#if` *symbol*|Supports conditional compilation. Code in the section after the `#if` is included if the *symbol* is defined. The symbol can also be negated with `!`.|
23-
|`#else`|Supports conditional compilation. Marks a section of code to include if the symbol used with the previous `#if` is not defined.|
18+
|`#if` *if-expression*|Supports conditional compilation. Code in the section after the `#if` is included if the *if-expression* evaluates to `defined` (see below).|
19+
|`#else`|Supports conditional compilation. Marks a section of code to include if the symbol used with the previous `#if` does not evaluate to `defined`.|
2420
|`#endif`|Supports conditional compilation. Marks the end of a conditional section of code.|
2521
|`#`[line] *int*,<br/>`#`[line] *int* *string*,<br/>`#`[line] *int* *verbatim-string*|Indicates the original source code line and file name, for debugging. This feature is provided for tools that generate F# source code.|
26-
|`#nowarn` *warningcode*|Disables a compiler warning or warnings. To disable multiple warning numbers on the same line, separate each string by a space. <br/> For example: `#nowarn 9 42`|
27-
28-
The effect of disabling a warning applies to the entire file, including portions of the file that precede the directive.|
22+
|`#nowarn` *warningcodes*|Disables one or more compiler warnings as specified by *warningcodes* (see below).|
23+
|`#warnon` *warningcodes*|Enables one or more compiler warnings as specified by *warningcodes* (see below).|
2924

3025
## Conditional Compilation Directives
3126

3227
Code that is deactivated by one of these directives appears dimmed in the Visual Studio Code Editor.
3328

34-
> [!NOTE]
35-
> The behavior of the conditional compilation directives is not the same as it is in other languages. For example, you cannot use Boolean expressions involving symbols, and `true` and `false` have no special meaning. Symbols that you use in the `if` directive must be defined by the command line or in the project settings; there is no `define` preprocessor directive.
36-
3729
The following code illustrates the use of the `#if`, `#else`, and `#endif` directives. In this example, the code contains two versions of the definition of `function1`. When `VERSION1` is defined by using the [-define compiler option](./compiler-options.md), the code between the `#if` directive and the `#else` directive is activated. Otherwise, the code between `#else` and `#endif` is activated.
3830

3931
[!code-fsharp[Main](~/samples/snippets/fsharp/lang-ref-2/snippet7301.fs)]
4032

41-
There is no `#define` preprocessor directive in F#. You must use the compiler option or project settings to define the symbols used by the `#if` directive.
42-
43-
Conditional compilation directives can be nested. Indentation is not significant for preprocessor directives.
44-
45-
You can also negate a symbol with `!`. In this example, a string's value is something only when _not_ debugging:
33+
The `#if` directive also accepts logical expressions:
4634

4735
```fsharp
48-
#if !DEBUG
49-
let str = "Not debugging!"
50-
#else
51-
let str = "Debugging!"
36+
#if SILVERLIGHT || COMPILED && (NETCOREFX || !DEBUG)
5237
#endif
5338
```
5439

40+
The following expressions can be used.
41+
42+
| if-expr | evaluation |
43+
| --- | --- |
44+
| `if-expr1 \|\| if-expr2` | `defined` if `if-expr1` or `if-expr2` is `defined`. |
45+
| `if-expr1 && if-expr2` | `defined` if `if-expr1` and `if-expr2` are `defined`. |
46+
| `!if-expr1` | `defined` if `if-expr1` is not `defined`. |
47+
| `( if-expr1 )` | defined if `if-expr1` is defined. |
48+
| `symbol` | `defined` if it is flagged as defined by the `-define` compiler option. |
49+
50+
The logical operators have the usual logical precedence.
51+
52+
There is no `#define` compiler directive in F#. You must use the compiler option or project settings to define the symbols used by the `#if` directive.
53+
54+
Conditional compilation directives can be nested. Indentation is not significant for compiler directives.
55+
5556
## NULLABLE directive
5657

5758
Starting with F# 9, you can enable nullable reference types in the project:
@@ -84,6 +85,42 @@ When you use the `#line` directive, file names must be enclosed in quotation mar
8485

8586
These tokens indicate that the F# code generated at this location is derived from some constructs at or near line `25` in `Script1`.
8687

88+
Note that `#line` directives do not influence the behavior of `#nowarn` / `#warnon`. These two directives always relate the the file that is being compiled.
89+
90+
## Warn Directives
91+
92+
Warn directives disable or enable specified compiler warnings for parts of a source file.
93+
94+
A warn directive is a single line of source code that consists of
95+
96+
- Optional leading whitespace
97+
- The string `#nowarn` or `#warnon`
98+
- Whitespace
99+
- One or more *warningcodes* (see below), separated by whitespace
100+
- Optional whitespace
101+
- Optional line comment
102+
103+
A *warningcode* is a sequence of digits (representing the warning number), optionally preceded by `FS`, optionally surrounded by double quotes.
104+
105+
A `#nowarn` directive disables a warning until a `#warnon` directive for the same warning number is found, or else until end of file. Similarly, a `#nowarn` directive disables a warning until a `#warnon` directive for the same warning numberis found, or else until end of file. Before and after such pairs, the compilation default applies, which is
106+
107+
- no warning if disabled by a --nowarn compiler option (or the respective msbuild property)
108+
- no warning for [opt-in warnings](./compiler-options.md#opt-in-warnings), unless enabled by the --warnon compiler option (or the respective msbuild property)
109+
110+
Here is a (contrived) example.
111+
112+
```
113+
module A
114+
match None with None -> () // warning
115+
let x =
116+
#nowarn 25
117+
match None with None -> 1 // no warning
118+
#warnon FS25
119+
match None with None -> () // warning
120+
#nowarn "FS25" FS007 "42"
121+
match None with None -> () // no warning
122+
```
123+
87124
## See also
88125

89126
- [F# Language Reference](index.md)

0 commit comments

Comments
 (0)