c99 vai all'inizializzazione passata

c99 vai all'inizializzazione passata

Puoi chiedere a gcc di avvisarti quando salti una definizione di variabile usando -Wjump-misses-init e poi puoi usare -Werror (o, più precisamente, -Werror=jump-misses-init ) per costringere gli utenti a gestirlo. Questo avviso è incluso in -Wc++-compat quindi gli sviluppatori di gcc sono consapevoli che il codice si comporta in modo diverso in C rispetto a C++.

Potresti anche modificare leggermente il codice:

int func()
{
    char *p1 = malloc(...);
    if (p1 == NULL)
        goto err_exit_1;

    char *p2 = malloc(...);
    if (p2 == NULL)
        goto err_exit_2;

    ...

err_exit_2:
    free(p2);
err_exit_1:
    free(p1);

    return -1;
}

... e continua ad accoppiare le etichette con le variabili inizializzate. Avrai lo stesso problema con la chiamata di molte altre funzioni con variabili nonalizzate, free è solo una più ovvia.


Un salto del genere è effettivamente consentito dallo standard, quindi questo non è un bug in GCC. La norma elenca questa situazione come avviso suggerito nell'allegato I.

L'unica restrizione imposta ai salti in C99 per quanto riguarda l'ambito è che è illegale saltare nell'ambito di una variabile di tipo modificato in modo variabile, come un VLA

int main() {
  int n = 5;
  goto label; // <- ERROR: illegal jump
  int a[n];
label:;
}

In altre parole, non è corretto dire che "un salto è solo un salto in C". I salti sono alquanto limitati quando si tratta di entrare nell'ambito delle variabili, anche se non così rigorosamente come in C++. La situazione che descrivi non è di quelle limitate.


Hmm, non è perché il nuovo standard consente dichiarazioni di variabili ovunque che sia sempre una buona idea usarlo. Nel tuo caso farei come se lo facessimo in C classico.

int func()
{
char *p1 = NULL;    /* So we have a defined value */
char *p2 = NULL;

  p1 = malloc(...);
  if(!p1)
    goto err_exit;

  p2 = malloc(...);
  if(!p2)
    goto err_exit;

  ...

  err_exit:
    free(p2);
    free(p1);

  return -1;
}