Mark a region in the source code that will only be included in the compilation when a logical condition evaluates to TRUE.
#if <logical_expression>
<SourceCode included if <logical_expression> evaluates to .T.>
[ #else
<SourceCode included if <logical_expression> othwerwise>
]
#endif
<logical_expression> : <expression>
<expression> : <unary_operator> <expression> // unary prefix expression
| <expression> <binary_operator> <expression> // binary numeric expression
| <expression> <shift_operator> <expression> // binary shift expression
| <expression> <comparison_operator> <expression> // binary logical expression
| <expression> <bitwise_operator> <expression> // binary bitwise expression
| <expression> <logical_operator> <expression> // binary logical expression
| <negation_operator> <expression> // negation expression
| <primary_expression> // primary expression
<unary_operator> : + | - | ++ | --
<binary_operator> : ^ | * | / | % | + | -
<shift_operator> : << | >>
<comparison_operator> : < | <= | > | >= | = | == | != | <>
<bitwise_operator> : & | |
<logical_operator> : .AND. | .OR. | .XOR.
<negation_operator> : ! | .NOT.
<primary_expression> : <literal_value> // literal expression
| ( <expression> ) // parenthesized expression
<literal_value> : <string_literal>
| <char_literal>
| <logical_literal>
| <integer>
| <double>
| <#define_constant>
<string_literal> : "double quoted"
| 'single_quoted'
| [block_quoted]
| e"escaped"
<char_literal> c'<char>'
<logical_literal> : .T. | TRUE | .F. | FALSE
The #if...#else...#endif directive forms a control structure for the preprocessor.
When the <logical_expression> evaluates to true (.T.), the preprocessor translates and outputs the source code located between the directives #if and #else to the intermediary file, and the source code between the directives #else and #endif is ignored.
If no #else directive is present, the preprocessor translates and outputs the source code located between the directives #if and #endif .
If the <logical_expression> evaluates to false (.F.) the source code between the directives #else and #endif is included only.
The <logical_expression> term can be formed using operands, compare operators and logical operators. A compare operations always requires two operands and will be evaluated prior to logical operations. The operands must be either string literals, numeric literals or logical literals or a valid #define constant that results to one of the mentioned literals.
A string will be recognized when it is enclosed within single or double quote characters. If an undefined constant is encountered the result of that term will be false (.F.).
A logical expression consists either of two expression and one logical operator, or simply of one literal.
When an expression mixes types then the preprocessor automatically converts types in the following order for comparisons and calculations:
1. String
2. Double
3. Integer
4. Logic
Example
#if 1 > "abc"
// the 1 is converted to "1" first before the comparison is done
? "Compare number and string"
#endif
#if 1.2 > FALSE
// the FALSE is converted to 0 first before the comparison is done
? "Compare number and string"
#endif
If one operand is of type |
Then the other operand is converted like this |
String |
Call .ToString() on the value |
Double or Decimal |
Integer: ToDouble() |
Integer |
Logic: TRUE = 1, FALSE = 0 |
Logical (The expression on the #if line) |
String: Null or Empty = FALSE, All others = TRUE |
String comparisons are done in case sensitive way using an Ordinal comparison. The '=' operator is NOT supported for string comparisons since the preprocessor does not know what the setting for "SetExact() is that you want to use. All comparisons are done with String.Compare().
In the FoxPro dialect the operators NOT, AND, OR and XOR are also available