2010-09-07 11 views
5

Durante la revisione della base di codice di Visual C++ ho trovato una cosa strana seguente. Un assert run-time (che è controllare le condizioni e un'eccezione se la condizione è violata) è stato utilizzato in un caso in cui la condizione potrebbe essere valutata al momento della compilazione:Qualsiasi motivo per utilizzare una dichiarazione di runtime invece di asserire in fase di compilazione?

assert(sizeof(SomeType) == sizeof(SomeOtherType)); 

chiaramente il compilatore valuterà la condizione e sostituire il codice che effettivamente essere sia

assert(true); 

che non fa nulla o

assert(false); 

che genera un'eccezione ogni volta che il controllo passa attraverso quella linea.

IMO un'assert in fase di compilazione avrebbe dovuto essere utilizzati, invece, per i seguenti motivi:

  • che esporrebbe la violazione condizioni in precedenza - in fase di compilazione - e
  • che avrebbe lasciato più pulita (quindi più veloce e più piccolo) codice macchina emesso

Sembra che l'asserzione in fase di compilazione sia l'unica cosa giusta. C'è qualche ragione possibile per preferire una dichiarazione di rincorsa qui?

+3

Mi sembra un WTF. – egrunin

+0

'assert' di solito non lancia un'eccezione ma piuttosto interrompe il programma. –

+0

Per ora non esiste alcuna dichiarazione standard in fase di compilazione. Questo fatto è piuttosto importante, specialmente nelle basi di codice meno recenti. –

risposta

15

Non c'è motivo di preferire un asserzione di run-time qui. Dovresti preferire gli errori in fase di compilazione rispetto agli errori di run-time, quindi non c'è mai un motivo, data l'opzione tra i due, per scegliere un asserimento in fase di esecuzione.

Tuttavia, se un assert statico non è un'opzione (non conosce il concetto di un assert statica, non sa come fare uno e non ne ha uno a disposizione, o sa come fare uno, ma non ha il tempo di farlo), una dichiarazione di runtime è la cosa migliore.

Con C++ 0x, la funzione integrata static_assert dovrebbe terminare tutti i motivi per utilizzare un'asserzione di runtime in cui un asserimento in fase di compilazione funzionerebbe.

4

Non possiamo dire senza contesto. Nel codice del modello, alcuni rami potrebbero essere irraggiungibili per alcune istanze. Un'asserzione in fase di compilazione sarebbe inappropriata, in quanto ciò rende l'intera funzione non corretta. Un assert(<type-dependent expression>) no.

E.g.

template <typename T> void foo(T t) 
{ 
    if (t < 0) { 
    assert(std::numeric_limits<T>::min() < 0); 
    T u = t - std::numeric_limits<T>::min(); 
    } 
} 

L'asserzione non può essere convertito in un assert statica, anche se l'asserzione di run-time non manca mai.

+0

Perché non si può fare un 'static_assert'? – GManNickG

+0

'assert (std :: numeric_limits :: min <0);' fallisce sempre, indipendentemente da T. – usta

+0

@usta: stai commentando la mancanza di una chiamata di funzione? @MSalters: Penso che tu volessi 'min()' –