Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the precedence of operators in C# Preprocessor Directives?

If I have a piece of code written in C# wrapped in an #if directive, what (if any) precedence is applied to any boolean operators that might be used in that directive?

In other words:

#if DEBUG || MYTEST && PLATFORM_WINDOWS
// ... Some code here
#endif

Will that be simply evaluated left to right as

#if (DEBUG || MYTEST) && PLATFORM_WINDOWS

And similarly, would

#if PLATFORM_WINDOWS && DEBUG || MYTEST

Be evaluated as

#if (PLATFORM_WINDOWS && DEBUG) || MYTEST

Or is there some precedence order for && vs ||?

Edit: To be clear, I am well aware that I can run the code myself to test it, and I have. I'm looking for an answer that gives me something official - a reference to documentation or the like, which can give me a deeper understanding of the underlying mechanics of directives. I'd like to know if there is a specifically intended behaviour or if this is purely something that is undefined.

like image 431
Blobinator Avatar asked Jun 20 '14 18:06

Blobinator


People also ask

What is a precedence of operators?

Operator Precedence ¶ The precedence of an operator specifies how "tightly" it binds two expressions together. For example, in the expression 1 + 5 * 3 , the answer is 16 and not 18 because the multiplication ("*") operator has a higher precedence than the addition ("+") operator.

What is operator precedence in C give example?

Operator precedence determines the grouping of terms in an expression and decides how an expression is evaluated. Certain operators have higher precedence than others; for example, the multiplication operator has a higher precedence than the addition operator.

What is the order of precedence of following operators?

Explanation: Order of precedence is (highest to lowest) a -> b -> c -> d. 2.


3 Answers

2.5.2 Pre-processing expressions

Evaluation of a pre-processing expression always yields a boolean value. The rules of evaluation for a pre-processing expression are the same as those for a constant expression (§7.19), except that the only user-defined entities that can be referenced are conditional compilation symbols

7.19 Constant expressions

The compile-time evaluation of constant expressions uses the same rules as run-time evaluation of non-constant expressions*, except that where run-time evaluation would have thrown an exception, compile-time evaluation causes a compile-time error to occur.

So the same operator precedence applies to pre-processing expressions, constant expressions and runtime evaluation.

7.3.1 Operator precedence and associativity

(...)

7.11 Logical AND &

7.11 Logical XOR ^

7.11 Logical OR |

7.12 Conditional AND &&

7.12 Conditional OR ||

(...)

From highest to lowest precedence.

like image 71
MarcinJuraszek Avatar answered Sep 18 '22 09:09

MarcinJuraszek


The precedence in preprocessor directives is the same as the usual precedence: && has a higher precedence than ||. To demonstrate this, run the following code:

#undef A
#define B
#define C
#if A && B || C
    Console.WriteLine(1);
#endif
#if (A && B) || C
    Console.WriteLine(2);
#endif
#if A && (B || C)
    Console.WriteLine(3);
#endif
#if B || C && A
    Console.WriteLine(4);
#endif
#if B || (C && A)
    Console.WriteLine(5);
#endif
#if (B || C) && A
    Console.WriteLine(6);
#endif

The output is:

1
2
4
5

Which shows that the parentheses are equivalent when they're around the &&, not the two items on the left.

like image 25
Tim S. Avatar answered Sep 20 '22 09:09

Tim S.


See 2.5.2 Pre-processing expressions in the C# Language Specification Version 5.0.

The specification doesn't talk about operator precedence, but it follows from the BNF grammar given in that section.

  1. Parentheses, constants (true, false) and conditional-symbols (PLATFORM_WINDOWS, DEBUG etc.)
  2. Unary !
  3. Equality ==, !=
  4. And &&
  5. Or ||

It also says:

When referenced in a pre-processing expression, a defined conditional compilation symbol has the boolean value true, and an undefined conditional compilation symbol has the boolean value false.

Evaluation of a pre-processing expression always yields a boolean value. The rules of evaluation for a pre-processing expression are the same as those for a constant expression (§7.19), except that the only user-defined entities that can be referenced are conditional compilation symbols.

like image 32
CodesInChaos Avatar answered Sep 17 '22 09:09

CodesInChaos