Conditional Directives
Function: tpp.c TPPLexer_Next
Function: tpp.c TPPLexer_EvalConst
Function: tpp.c TPPLexer_EvalConst1
The c11 standard defines a variety of directives, to control what code is visible to the compiler after preprocessing is done. TPP implements all of them with only minor additions:
#if#elif#else#endif#ifdef#ifndefConditional expressions that follow #if and #elif follow the obvious rules and allow the use of all of the c operators. The internal value used for evaluating the expression is usually a 64-bit integer (but no guaranties are given on that).
Supported operators are (in precedence order):
, (comma operator: only available, when evaluating using TPPLexer_EvalConst)? (Conditional operator)|| (Logical or)^^ (Extension: Logical xor)&& (Logical and)| (Or)^ (Xor)& (And)== (Equal) != (Not equal)< (Lower than) <= (Lower equal) > (Greater than) >= (Greater equal)<< (Shift left) >> (Shift right)+ (Plus) - (Minus)* (Multiply) / (Divide) % (Modulo)+ (Unary plus) - (Unary minus) ! (Logical not) ~ (Complement) <int> (Unary constant) (...) (Parenthesis)Check: logical xor: #if __has_feature(tpp_token_lxor) || __has_extension(tpp_token_lxor)
Directives may not cross multiple files and a warning is emitted, if not all #if-blocks are closed at the end of a file.
The following example shows the different directives working together:
#if 10+20 == 30
// Enabled
#elif 1
// Disabled
#else
// Disabled
#endif
#if 49*10 == 100
// Disabled
#elif 42 != 42
// Disabled
#elif 42 == 42
// Enabled
#else
// Disabled
#endif
#define foobar
#if defined(foobar)
// Enabled
#endif
#if !defined foobar
// Disabled
#elif defined foobar
// Enabled
#endif
#ifdef foobar
// Enabled
#endif
#ifndef foobar
// Disabled
#endif
#if 1
#ifdef foobar
#ifndef foobar2
// Enabled
#endif
#endif
#endif