Skip to content

update compiler directives page of FSharp reference #47130

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 24 additions & 16 deletions docs/fsharp/language-reference/compiler-directives.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,39 +19,45 @@

|Directive|Description|
|---------|-----------|
|`#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 `!`.|
|`#else`|Supports conditional compilation. Marks a section of code to include if the symbol used with the previous `#if` is not defined.|
|`#if` *if-expression*|Supports conditional compilation. Code in the section after the `#if` is included if the *if-eyxpression* evaluates to `defined` (see below).|
|`#else`|Supports conditional compilation. Marks a section of code to include if the symbol used with the previous `#if` does not evaluate to `defined`.|
|`#endif`|Supports conditional compilation. Marks the end of a conditional section of code.|
|`#`[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.|
|`#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`|
|`#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`<br/> The warning is disabled until eof or until a `#warnon` directive for that same warning number is foud.|
|`#warnon` *warningcode*|Enables a compiler warning (or warnings) that was disabled by a compiler option or by a `#nowarn` directive..<br/> The warning is enabled until eof or until a `#nowarn` directive for that same warning number is found.|
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to list also the #nowarn "42" option (with quotes), since it is what most codebases use?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe include pseudogrammar:

#nowarn (int list | string list) , where strings are without the FS prefix?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I will add a whole section then with more details. I will come back to it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a more detailed section on the warn directives.

In this context I also removed the redundant term "preprocessor directives" from the page. In the F# spec, the term "preprocessor directive" is used only for what in this document is called "conditional compilation directives". Also, the one and only compiler has no separate preprocessor, so "compiler directives" seems to be the right general term.


The effect of disabling a warning applies to the entire file, including portions of the file that precede the directive.|

Check failure on line 29 in docs/fsharp/language-reference/compiler-directives.md

View workflow job for this annotation

GitHub Actions / lint

Multiple consecutive blank lines

docs/fsharp/language-reference/compiler-directives.md:29 MD012/no-multiple-blanks Multiple consecutive blank lines [Expected: 1; Actual: 2] https://github.com/DavidAnson/markdownlint/blob/v0.38.0/doc/md012.md
## Conditional Compilation Directives

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

> [!NOTE]
> 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.

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.

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

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.

Conditional compilation directives can be nested. Indentation is not significant for preprocessor directives.

You can also negate a symbol with `!`. In this example, a string's value is something only when _not_ debugging:
The `#if` directive also accepts logical expressions:

```fsharp
#if !DEBUG
let str = "Not debugging!"
#else
let str = "Debugging!"
#if SILVERLIGHT || COMPILED && (NETCOREFX || !DEBUG)
#endif
```

The following expressions can be used.

| if-expr | evaluation |
| --- | --- |
| `if-expr1 \|\| if-expr2` | `defined` if `if-expr1` or `if-expr2` is `defined`. |
| `if-expr1 && if-expr2` | `defined` if `if-expr1` and `if-expr2` are `defined`. |
| `!if-expr1` | `defined` if `if-expr1` is not `defined`. |
| `( if-expr1 )` | defined if `if-expr1` is defined. |
| `symbol` | `defined` if it is flagged as defined by the `-define` compiler option. |

The logical operators have the usual logical precedence.

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.

Conditional compilation directives can be nested. Indentation is not significant for preprocessor directives.

## NULLABLE directive

Starting with F# 9, you can enable nullable reference types in the project:
Expand Down Expand Up @@ -84,6 +90,8 @@

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

Note that `#line` directives do not influence the behavior of `#nowarn` / `#warnon`. These two directives always relate the the file that is being compiled.

## See also

- [F# Language Reference](index.md)
Expand Down
Loading