Fai attenzione all'operatore "continua" all'interno di do {...} mentre (...)

Fai attenzione all'operatore "continua" all'interno di do {...} mentre (...)

Frammento tratto dall'Haiku progetto (erede di BeOS). Il codice contiene un errore che l'analizzatore diagnostica nel modo seguente:V696 L'operatore 'continue' interromperà il ciclo 'do { … } while (FALSE)' perché la condizione è sempre falsa.

do {
  ....
  if (appType.InitCheck() == B_OK
    && appType.GetAppHint(&hintRef) == B_OK
    && appRef == hintRef)
  {
    appType.SetAppHint(NULL);
    // try again
    continue;
  }
  ....
} while (false);

Spiegazione

Il modo continua funziona all'interno del ciclo do-while, non è il modo in cui alcuni programmatori si aspettano. Quando continua si incontra, ci sarà sempre un controllo della condizione di terminazione del loop. Cercheremo di spiegarlo in modo più dettagliato. Supponiamo che il programmatore scriva codice come questo:

for (int i = 0; i < n; i++)
{
  if (blabla(i))
    continue;
  foo();
}

O così:

while (i < n)
{
  if (blabla(i++))
    continue;
  foo();
}

La maggior parte dei programmatori per intuizione comprende che quando si incontra continue, la condizione di controllo (i

do
{
  if (blabla(i++))
    continue;
  foo();
} while (i < n);

l'intuizione spesso fallisce, poiché non vedono una condizione al di sopra del continua , e sembra loro che il continua attiverà immediatamente un'altra iterazione del ciclo. Non è così e continua fa come sempre – fa sì che la condizione di controllo venga rivalutata.

Dipende dalla pura fortuna se questa mancanza di comprensione di continue porterà a un errore. Tuttavia, l'errore si verificherà sicuramente se la condizione del ciclo è sempre falsa, come nel frammento di codice riportato sopra, in cui il programmatore ha pianificato di eseguire determinate azioni attraverso successive iterazioni. Un commento nel codice "//riprova" mostra chiaramente la loro intenzione di farlo. Ovviamente non ci sarà alcun "di nuovo", poiché la condizione è sempre falsa, quindi una volta continua viene rilevato, il ciclo terminerà.

In altre parole, risulta che nella costruzione di questo do {…} while (false), il continua equivale a usare break .

Codice corretto

Ci sono molte opzioni per scrivere il codice corretto. Ad esempio, crea un ciclo infinito e usa continua eseguire il ciclo e interrompere per uscire.

for (;;) {
  ....
  if (appType.InitCheck() == B_OK
    && appType.GetAppHint(&hintRef) == B_OK
    && appRef == hintRef)
  {
    appType.SetAppHint(NULL);
    // try again
    continue;
  }
  ....
  break;
};

Raccomandamento

Cerca di evitare continua inside do { … } while (…). Anche se sai davvero come funziona. Il fatto è che potresti scivolare e fare questo errore e/o che i tuoi colleghi potrebbero leggere il codice in modo errato e quindi modificarlo in modo errato. Non smetteremo mai di dirlo:un buon programmatore non è colui che conosce e usa i diversi trucchi del linguaggio, ma colui che scrive codice chiaro e comprensibile, che anche un principiante può comprendere.

Scritto da Andrey Karpov.
Questo errore è stato trovato con PVS-Studio strumento di analisi statica.