Domanda

int main()
{
  int var = 0;; // Typo which compiles just fine
}
È stato utile?

Soluzione

Questo è il modo in cui C e C ++ esprimono NOP .

Altri suggerimenti

In quale altro modo assert(foo == bar); può essere compilato fino a zero quando NDEBUG è stato definito?

Ovviamente possiamo dire cose come

for(;;) {
  // stuff
}

Chi potrebbe vivere senza quello?

Non sono un designer di lingue, ma la risposta che darei è " perché no? " Dal punto di vista della progettazione linguistica, si vogliono che le regole (cioè la grammatica) siano il più semplice possibile.

Per non parlare del fatto che " espressioni vuote " hanno usi, ad esempio

per (i = 0; i < INSANE_NUMBER; i ++);

Will dead-wait (non un buon uso, ma comunque un uso).

MODIFICA: Come sottolineato in un commento a questa risposta, qualsiasi compilatore degno di nota probabilmente non sarà impegnato ad attendere questo ciclo e ad ottimizzarlo via. Tuttavia, se ci fosse qualcosa di più utile in for head stesso (diverso da i ++), che ho visto fatto (stranamente) con l'attraversamento della struttura dei dati, allora immagino che potresti ancora costruire un ciclo con un corpo vuoto (usando / abusare del " per " costrutto).

Onestamente non so se questa è la vera ragione, ma penso che qualcosa che abbia più senso sia pensarci dal punto di vista di un implementatore di compilatori.

Ampie porzioni di compilatori sono costruite con strumenti automatizzati che analizzano classi speciali di grammatiche. Sembra molto naturale che utili grammatiche consentirebbero dichiarazioni vuote. Sembra un lavoro superfluo rilevare un & Quot; errore & Quot; quando non cambia la semantica del tuo codice. L'istruzione vuota non farà nulla, poiché il compilatore non genererà codice per tali istruzioni.

Mi sembra che questo sia solo il risultato di " Non aggiustare qualcosa che non è rotto " ...

Vuoi essere in grado di fare cose come

while ( fnorble(the_smurf) == FAILED )
    ;

e non

while ( fnorble(the_smurf) == FAILED )
    do_nothing_just_because_you_have_to_write_something_here();

Ma! Per favore non scrivere la frase vuota sulla stessa riga, in questo modo:

while ( fnorble(the_smurf) == FAILED );

Questo è un ottimo modo per confondere il lettore, poiché è facile perdere il punto e virgola e quindi pensare che la riga successiva sia il corpo del ciclo. Ricorda: la programmazione riguarda davvero la comunicazione, non con il compilatore, ma con altre persone che leggeranno il tuo codice. (O con te stesso, tre anni dopo!)

OK, aggiungerò questo allo scenario peggiore che potresti effettivamente utilizzare:

for (int yy = 0; yy < nHeight; ++yy)
{
    for (int xx = 0; xx < nWidth; ++xx)
    {
        for (int vv = yy - 3; vv <= yy + 3; ++vv)
        {
            for (int uu = xx - 3; uu <= xx + 3; ++uu)
            {
                if (test(uu, vv))
                {
                    goto Next;
                }
            }
        }

    Next:;
    }
}   

Il caso più comune è probabilmente

int i = 0;
for (/* empty*/; i != 10; ++i) {
    if (x[i].bad) break;
}
if (i != 10) {
    /* panic */
}

Quando si utilizza ';' si prega di essere consapevoli anche di una cosa. Questo è ok:

a ? b() : c();

Tuttavia questo non verrà compilato:

a ? b() : ; ;
while(1){
    ; /* do nothing */
}

Ci sono momenti in cui vuoi sederti e non fare nulla. Un'applicazione incorporata guidata da evento / interruzione o quando non si desidera uscire da una funzione, ad esempio durante l'impostazione di thread e in attesa del primo cambio di contesto.

Esempio: http://lxr.linux.no/ linux + v2.6.29 / arch / m68k / mac / misc.c # L523

Esistono già molte risposte valide ma non ho visto l'esempio dell'ambiente produttivo.

Qui è l'implementazione di FreeBSD di strlen:

size_t
strlen(const char *str)
{
    const char *s;

    for (s = str; *s; ++s)
        ;
    return (s - str);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top