问题
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.
回答1:
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.
回答2:
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.
- Parentheses, constants (
true
,false
) and conditional-symbols (PLATFORM_WINDOWS
,DEBUG
etc.) - Unary
!
- Equality
==
,!=
- And
&&
- 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.
回答3:
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.
回答4:
I believe that the && operator has higher precedence than the || Operator in C# as shown here, http://msdn.microsoft.com/en-us/library/aa691323(v=vs.71).aspx.
So your code would then be evaluated :
#if DEBUG || MYTEST && PLATFORM_WINDOWS
// ... Some code here
#endif
would be evaluated as
#if (MYTEST && PLATFORM_WINDOWS) || DEBUG
// ... Some code here
#endif
来源:https://stackoverflow.com/questions/24333119/what-is-the-precedence-of-operators-in-c-sharp-preprocessor-directives