Directive #if Foundation

Compiles code depending on evaluation of expression

Syntax
#if <logical_expression>
    <SourceCode included if <logical_expression> evaluates to .T.>
[ #else
    <SourceCode included if <logical_expression> othwerwise>
]
#endif
<logical_expression>:
<operand> [.AND.|.OR. <operand> [<logical_expression>]]
<operand>:
<literal_value> [<|<=|==|!=||>=|> <preproc_literal>]
<literal_value>:
"string literal" | 'string literal' | .T.|.F. | <integer> | <#define_constant>
Parameters
<logical_expression>
<logical_expression> designates a preprocessor expression which can consist of operands and operators.
Description

The directive #if...#else...#endif 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 operands and one logical operator, or simply of one literal. In the latter case, a logical value will be obtained by performing .NOT. Empty(<operand>) internally.

Supported logical operators for #if
Logical operator
.AND.
.OR.

In general, the Xbase++ preprocessor is case sensitive. Therefore, logical operators in #if expressions must be coded in upper case.

The .NOT. operator is not supported here. To invert the result of the expression, use De Morgan's rules, for example:

// an expression having .NOT. 
#if .NOT. (x > y .AND. A_TRUE_DEFINE) 
// is transformed into 
#if x <= y .OR. A_TRUE_DEFINE == .F. 

Supported compare operators for #if
Compare operator
>
>=
==
!=
<=
<

If the literals are of different data types, the value of the more primitive type will be transformed to the more complex type before the comparison:

<logic> -> <numeric> -> <string> 

// example for implict conversions 
#if .T. > 0 .AND. 1 > "0" 
//  (.T. -> 1) > 0 .AND. (1 -> "1") > "0" 
#endif 

Examples
Possible #if usage patterns
// 
// 
#define VERSION_MIN 1 

PROCEDURE Main() 

  #if TARGET_VER < VERSION_MIN 
     ? "You need to upgrade to version" + str(VERSION_MIN) 
  #endif 

  #if .F. 
  #stdout This never shows up 
  #endif 

  #if .T. .AND. 1>0 .AND. "AA" < "BB" 
  #stdout This is always true 
  #endif 

  #if 1 < "2" 
  #stdout A numeric will be converted to string before the comparison. 
  #endif 

  #if 1 == .T. 
  #stdout A logic literal will be converted to numeric before the comparison. 
  #endif 

RETURN 
Feedback

If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.