2013-07-25 20 views
51

Dopo un errore di battitura, la seguente espressione (semplificato) compilato ed eseguito:Cosa significa questa espressione e perché viene compilata?

if((1 == 2) || 0 (-4 > 2)) 
    printf("Hello"); 

naturalmente, lo 0 non dovrebbe essere lì.

Perché compila e cosa significa l'espressione?

L'originale (semplificato) dovrebbe essere simile a questo:

if((1 == 2) || (-4 > 2)) 
    printf("Hello"); 

niente di tutto questo si compila:

if((1 == 2) || true (-4 > 2)) 
    printf("Hello"); 

if((1 == 2) || 1 (-4 > 2)) 
    printf("Hello"); 

if((1 == 2) || null (-4 > 2)) 
    printf("Hello"); 
+3

Ho appena provato questo e ottenuto [avviso C4353] (http://msdn.microsoft.com/en-us/library/2a68558f.aspx): "estensione non standard utilizzata: costante 0 come espressione di funzione. '__noop' funzione intrinseca invece " – Rup

+3

ho ottenuto l'errore: l'oggetto chiamato '0' non è una funzione ' –

+3

Questo ha già avuto risposta a http://stackoverflow.com/questions/2198950/why-is-void-0-a-no-operation-in-c-and-c –

risposta

8

In effetti è specifico Microsoft.

Per scopi di debug, è possibile utilizzare __noop intrinseco, specifica che la funzione e i parametri non saranno valutati.

Nel tuo caso, Microsoft compilatore pensa che si sta tentando di utilizzare 0 a fare lo stesso, è per questo che funziona, ma per esempio, su VS2012 dà l'avvertimento:

warning C4353: nonstandard extension used: constant 0 as function expression. Use '__noop' function intrinsic instead. 

vedere questo per maggiori informazioni: http://msdn.microsoft.com/en-us/library/2a68558f(v=vs.71).aspx

+0

L'importante è che anche i parametri non vengano valutati. – huebe

+0

Cosa restituisce questa funzione noop-edita? 'if ((1 == 2) || 0 (-4> 2))' richiede un valore booleano. È un numero casuale da un registro? – Kane

14

immagino che fosse interpretato come

if((1 == 2) || NULL (-4 > 2)) 
    printf("Hello"); 

dove NULL è un function-pointer, di default return int ... Ciò che effettivamente accade in runtime dipende dalla piattaforma

+0

L'importanza della sicurezza del tipo ... C++ 11 rende le cose di più sicuro con questo tipo di problemi introducendo un altro tipo di valore NULL –

1

In ubuntu è mostrando errore

int main() 
{ 
if((1 == 2) || 0 (-4 > 2)) 
     printf("Hello"); 
} 

o/p

niew1.c:3:19: error: called object â0â is not a function 
0

Probabilmente 0 è realizzata mediante fusione per un puntatore alla funzione qui. cast esplicito può apparire come segue:

if((1 == 2) || ((int (*)(int)) 0) (-4 > 2)) 
     printf("Hello"); 

Tuttavia, non ho congetture su quale funzione 0 è realizzata mediante fusione per in modo implicito nel tuo esempio.

9

Visual Studio 2012 vi dà il seguente avviso:

avvertimento C4353: estensione non standard utilizzata: costante 0 come espressione di una funzione. Utilizzare la funzione '__noop' intrinseca invece

è un modo non standard per inserire un "nessuna operazione" Manuale assemblatore a quel punto della valutazione dell'espressione

26

Sembra che questo è un Visual C++ estensione per supportare un particolare 'idioma non definito' funzione. Dalla pagina warning C4353:

// C4353.cpp 
// compile with: /W1 
void MyPrintf(void){}; 
#define X 0 
#if X 
    #define DBPRINT MyPrint 
#else 
    #define DBPRINT 0 // C4353 expected 
#endif 
int main(){ 
    DBPRINT(); 
} 

l'intenzione è che DBPRINT è un no-op. L'avviso suggerisce invece #define DBPRINT __noop, utilizzando invece l'estensione __noop di VC.

Se si visualizza l'elenco di assiemi per l'output, verrà visualizzata la seconda clausola, anche in modalità di debug.

Problemi correlati