2014-06-20 11 views
5

Se ho un codice scritto in C# racchiuso in una direttiva #if, quale (eventuale) precedenza viene applicata a qualsiasi operatore booleano che potrebbe essere utilizzato in tale direttiva?Qual è la precedenza degli operatori nelle direttive per il preprocessore C#?

In altre parole:

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

Sarà che essere semplicemente valutati da sinistra a destra, come

#if (DEBUG || MYTEST) && PLATFORM_WINDOWS 

E allo stesso modo, sarebbe

#if PLATFORM_WINDOWS && DEBUG || MYTEST 

essere valutata come

#if (PLATFORM_WINDOWS && DEBUG) || MYTEST 

Oppure esiste un ordine di precedenza per & & vs ||?

Modifica: Per essere chiari, sono ben consapevole di poter eseguire il codice personalmente per testarlo, e lo sono. Sto cercando una risposta che mi doni qualcosa di ufficiale - un riferimento alla documentazione o simili, che possa darmi una comprensione più profonda della meccanica di fondo delle direttive. Mi piacerebbe sapere se esiste un comportamento specifico o se questo è puramente qualcosa che non è definito.

+4

La parentesi IMO dovrebbe essere utilizzata comunque, per evitare di pensare in alto e tale confusione – thumbmunkeys

+5

Perché non eseguire alcuni test e dirci?Questo è qualcosa che potresti facilmente scoprire da solo. –

+0

La soluzione semplice, che ha anche enormi benefici di leggibilità, è quella di limitarsi a parentesi da soli. – qaphla

risposta

12

2.5.2 espressioni di pre-elaborazione

Valutazione di un'espressione pre-elaborazione produce sempre un valore booleano . Le regole di valutazione per un'espressione pre-elaborazione sono gli stessi di quelli per un'espressione costante (§7.19), tranne che le uniche entità definiti dall'utente che possono essere di riferimento sono condizionali simboli di compilazione

7,19 espressioni costanti

La valutazione in fase di compilazione delle espressioni costanti utilizza le stesse regole di run-time valutazione di espressioni non costanti *, tranne per il caso in cui la valutazione del tempo di esecuzione genera un'eccezione, la valutazione in fase di compilazione causa un errore in fase di compilazione.

Quindi la stessa precedenza di operatore si applica alle espressioni di pre-elaborazione, alle espressioni costanti e alla valutazione runtime.

7.3.1 Precedenza degli operatori e l'associatività

(...)

7,11 logico AND &

7,11 XOR logico^

7.11 OR logico |

7,12 condizionato e & &

7,12 condizionale OR ||

(...)

dal più alto al più basso la precedenza.

+0

Wow è stato veloce - è che una specifica più vecchia quella che stavo guardando http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-334.pdf ha 2.5.2 a 9.5.2 ecc – Andrew

+2

È da spec. C# 5.0. Quello a cui ti sei collegato è il 2006 :) Le specifiche C# sono parte delle risorse di installazione di VS ora: http://msdn.microsoft.com/en-us/library/ms228593.aspx – MarcinJuraszek

+0

ah che lo spiega - pensavo che i numeri più bassi significavano più vecchi – Andrew

0

Credo che l'operatore & & abbia precedenza più alta di || Operatore in C# come mostrato qui, http://msdn.microsoft.com/en-us/library/aa691323(v=vs.71).aspx.

Così il vostro codice sarebbe poi essere valutata:

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

sarebbe valutato come

#if (MYTEST && PLATFORM_WINDOWS) || DEBUG 
// ... Some code here 
#endif 
+0

Questo vale per le espressioni C# (e quasi tutte le altre lingue), ma non sono stato in grado di trovare un riferimento che affermi esplicitamente che ciò è vero per i condizionali di preprocesso * C# *. Mostrare un risultato reale testato aggiungerebbe delle prove alla richiesta, trovando un riferimento/una specifica ufficiale, ancora di più. – user2864740

+0

@ user2864740 Questo è esattamente ciò che l'OP è stato chiesto di fare nei commenti contro la domanda! – ClickRick

7

Vedi 2.5.2 espressioni pre-elaborazione nel del linguaggio C# Specification Version 5.0.

La specifica non parla della precedenza degli operatori, ma segue dalla grammatica BNF fornita in quella sezione.

  1. Parentesi, costanti (true, false) e condizionali-simboli (PLATFORM_WINDOWS, DEBUG etc.)
  2. unario !
  3. Uguaglianza ==, !=
  4. E &&
  5. O ||

Si dice anche:

quando si fa riferimento in un'espressione di pre-elaborazione, un simbolo di compilazione condizionale e definita ha il valore booleano vero, e un simbolo di compilazione condizionale definito ha il valore booleano falso.

La valutazione di un'espressione di pre-elaborazione fornisce sempre un valore booleano.Le regole di valutazione per un'espressione di pre-elaborazione sono le stesse di quelle per un'espressione costante (§7.19), tranne per il fatto che le sole entità definite dall'utente che possono essere referenziate sono simboli di compilazione condizionale.

1

La precedenza in direttive del preprocessore è lo stesso del usual precedence: && ha una priorità più alta rispetto ||. A dimostrazione di ciò, eseguire il seguente codice:

#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 

L'output è:

1 
2 
4 
5 

che dimostra che le parentesi sono equivalenti quando sono intorno al &&, non i due elementi a sinistra.

Problemi correlati