2014-06-20 6 views
5

Wenn ich einen Codeabschnitt in C# geschrieben habe, der in eine #if-Direktive eingebettet ist, welche (wenn überhaupt) Präzedenz wird auf alle booleschen Operatoren angewendet, die in dieser Direktive verwendet werden könnten?Welchen Vorrang haben Operatoren in C# -Preprozessor-Direktiven?

Mit anderen Worten:

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

Wird das einfach nach rechts, wie

#if (DEBUG || MYTEST) && PLATFORM_WINDOWS 

Und in ähnlicher Weise nach links ausgewertet werden, würde

#if PLATFORM_WINDOWS && DEBUG || MYTEST 

als

bewertet werden
#if (PLATFORM_WINDOWS && DEBUG) || MYTEST 

Oder gibt es eine Reihenfolge für & & vs ||?

Edit: Um klar zu sein, mir ist klar, dass ich den Code selbst ausführen kann, um es zu testen, und ich habe. Ich suche nach einer Antwort, die mir etwas Offizielles gibt - ein Verweis auf Dokumentation oder Ähnliches, was mir ein tieferes Verständnis der zugrunde liegenden Mechanismen von Direktiven geben kann. Ich würde gerne wissen, ob es ein bestimmtes beabsichtigtes Verhalten gibt oder ob das etwas Undefiniertes ist.

+4

IMO Klammer sollte sowieso verwendet werden, um Denken zu vermeiden Overhead und solche Verwirrung – thumbmunkeys

+5

Warum nicht einige Tests laufen lassen und uns sagen?Das können Sie leicht selbst herausfinden. –

+0

Die einfache Lösung, die auch große Vorteile bei der Lesbarkeit bietet, besteht darin, sie nur in Klammern zu setzen. – qaphla

Antwort

12

2.5.2 Vorbearbeitung Ausdrücke

Auswertung einer Vorbearbeitung Ausdruck ergibt immer einen Booleschen Wert. Die Regeln der Bewertung für eine Vorbearbeitung Ausdruck sind die gleichen wie die für einen konstanten Ausdruck (§7.19), mit der Ausnahme, dass die einzigen benutzerdefinierte Entitäten, auf die verwiesen werden können, sind bedingte Kompilierung Symbole

7,19 konstante Ausdrücke

Die Kompilierung-Auswertung von konstanten Ausdrücken die gleichen Regeln wie Laufzeit verwendet Auswertung von nicht konstanten Ausdrücken *, außer dass die Laufzeitauswertung eine Ausnahme ausgelöst hätte, verursacht die Auswertung der Kompilierzeit einen Fehler bei der Kompilierung.

So ist der gleiche Operator Vorrang gilt Ausdrücke Verarbeitung vor, konstante Ausdrücke und Laufzeitauswertung.

7.3.1 Operator Vorrang und Assoziativität

(...)

7,11 Logisches UND &

7,11 Logische XOR^

7,11 Logisches ODER |

7,12 Conditional UND & &

7,12 bedingt oder ||

(...)

vom höchsten zum niedrigsten Vorrang.

+0

Wow das war schnell - ist das eine ältere Spezifikation die ich sah http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-334.pdf hat 2.5.2 bei 9.5.2 usw. – Andrew

+2

Es ist von C# 5.0 spec. Das, mit dem Sie verlinkt haben, ist 2006 :) C# spec ist jetzt ein Teil der VS-Installationsressourcen: http://msdn.microsoft.com/en-us/library/ms228593.aspx – MarcinJuraszek

+0

ah das erklärt es - gedachte niedrigere Zahlen bedeuteten älter – Andrew

0

Ich glaube, dass der & & Operator höhere Priorität hat als die || Operator in C# wie hier gezeigt, http://msdn.microsoft.com/en-us/library/aa691323(v=vs.71).aspx.

So würde der Code dann ausgewertet werden:

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

als

bewertet werden würde
#if (MYTEST && PLATFORM_WINDOWS) || DEBUG 
// ... Some code here 
#endif 
+0

Dies gilt für C# -Ausdrücke (und fast jede andere Sprache), aber ich konnte keinen Verweis finden, der explizit besagt, dass dies für C# * -Vorprozess * -Konditionale gilt. Das Zeigen eines tatsächlich getesteten Ergebnisses würde dem Anspruch einen Beweis hinzufügen und sogar eine offizielle Referenz/Spezifikation finden. – user2864740

+0

@ user2864740 Genau das wurde vom OP in den Kommentaren gegen die Frage verlangt! – ClickRick

7

Siehe 2.5.2 Vorbearbeitung Ausdrücke im C# Language Specification Version 5.0.

Die Spezifikation spricht nicht über Operator Vorrang, aber es folgt aus der BNF Grammatik in diesem Abschnitt gegeben.

  1. Klammerung, Konstanten (true, false) und bedingte-Symbole (PLATFORM_WINDOWS, DEBUG etc.)
  2. Unary !
  3. Gleichheit ==, !=
  4. Und &&
  5. Oder ||

Er sagt auch:

Wenn in einer Vorverarbeitung Ausdruck verwiesen, eine definierte bedingte Kompilierung Symbol hat den Booleschen Wert true, und eine nicht definierte bedingte Kompilierung Symbol hat den booleschen Wert false.

Die Auswertung eines Vorverarbeitungsausdrucks liefert immer einen booleschen Wert.Die Bewertungsregeln für einen vorverarbeitenden Ausdruck sind dieselben wie für einen konstanten Ausdruck (§7.19), außer dass die einzigen benutzerdefinierten Entitäten, auf die verwiesen werden kann, Symbole für bedingte Kompilierung sind.

1

Der Vorrang in Präprozessordirektiven ist das gleiche wie die usual precedence: && hat eine höhere Priorität als ||. Um dies zu demonstrieren, führen Sie den folgenden Code ein:

#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 

Die Ausgabe lautet:

1 
2 
4 
5 

, die zeigt, dass die Klammern äquivalent sind, wenn sie um die && sind, nicht die beiden Elemente auf der linken Seite.