Show/Hide Toolbars

XSharp

Purpose

Mark a region in the source code that will only be included in the compilation when a logical condition evaluates to TRUE.

Syntax

#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

Description

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.

 

Type conversions

 

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

Conversions
For comparisons and calculation operators the types of the 2 operands are compared. If they are equal then no conversion is needed. If they are not of the same type then the following rules are applied.

 

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()
Logical: TRUE = 1.0, FALSE = 0.0

Integer

Logic: TRUE = 1, FALSE = 0

Logical (The expression on the #if line)

String: Null or Empty = FALSE, All others = TRUE
Integer: 0 = FALSE, All others = TRUE
Double: 0.0 = FALSE, All others = TRUE

 

Comparison operations

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().

 

Dialects

In the FoxPro dialect the operators NOT, AND, OR and XOR are also available