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
#ifndef
Conditional 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):
1. ,
(comma operator: only available, when evaluating using TPPLexer_EvalConst
)
2. ?
(Conditional operator)
3. ||
(Logical or)
4. ^^
(Extension: Logical xor)
5. &&
(Logical and)
6. |
(Or)
7. ^
(Xor)
8. &
(And)
9. ==
(Equal) !=
(Not equal)
10. <
(Lower than) <=
(Lower equal) >
(Greater than) >=
(Greater equal)
11. <<
(Shift left) >>
(Shift right)
12. +
(Plus) -
(Minus)
13. *
(Multiply) /
(Divide) %
(Modulo)
14. +
(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