Menu

Commenti in C: // e /* */ spiegati

Il C ha due stili di commento, quello su una riga // e quello su più righe /* */, con storie diverse e una trappola sull'annidamento. Ecco come usarli entrambi e cosa vale la pena commentare e cosa no.

Questa pagina include editor eseguibili: modifica, esegui e vedi subito l'output.

Un commento è testo che il compilatore butta via. Esiste solo per le persone che leggeranno il codice in seguito, e una di queste di solito sei tu. Il C offre due forme, e capire quando usare l'una o l'altra richiede circa due minuti.

Le due forme

Eseguilo: l'output è una sola riga. Entrambi i commenti sono stati eliminati prima ancora che il compilatore analizzasse il programma: non costano nulla a runtime e non aggiungono nulla all'eseguibile.

// arriva fino alla fine della riga fisica. Su quella riga non può seguire nient'altro, quindi questo non funziona come sembra:

int x = 5;  // imposta x a cinque  int y = 6;   /* y non viene mai dichiarata */

/* ... */ termina al primo */, ovunque si trovi. Può iniziare e finire a metà riga, cosa che ogni tanto è utile:

int total = price /* tasse escluse */ + shipping;

Perché esistono due stili

/* */ è il C originale, del 1972. // arriva dal C++ ed è stato aggiunto ufficialmente al C solo con C99. Questa storia spiega una cosa che noterai leggendo codice più vecchio: le librerie scritte per essere portabili su C89 usano /* */ anche per i commenti di una riga, perché // non compilerebbe sulle vecchie toolchain che supportavano ancora.

Oggi ogni compilatore che probabilmente userai accetta entrambi. Usa // per le note normali e /* */ quando un commento occupa davvero più righe. Se lavori con un compilatore embedded molto vecchio, verifica prima di affidarti a //.

I commenti non si annidano

Questa è l'unica vera trappola:

/* Disattiva questa sezione per ora
   int a = compute();
   /* il classico helper: tienilo d'occhio */
   int b = a * 2;
*/

Il commento a blocco termina al primo */, quello sulla riga 3. Le righe 4 e 5 tornano quindi a essere codice attivo, e il */ finale sulla riga 6 è un errore di sintassi. Il messaggio del compilatore indica l'ultima riga e non aiuta per niente a capire la causa.

La soluzione è usare invece il preprocessore, che gestisce l'annidamento:

#if 0
    int a = compute();
    /* il classico helper: tienilo d'occhio */
    int b = a * 2;
#endif

#if 0 non è mai vero, quindi il preprocessore elimina tutto fino a #endif prima che il compilatore lo veda. Funziona anche con commenti, virgolette e altri blocchi #if all'interno, ed è facile da cercare quando fai pulizia.

Commentare codice durante il debug

Rimuovere temporaneamente una riga è l'uso quotidiano più comune dei commenti. Quando un programma si comporta male, disattivare un'istruzione alla volta ti dice quale conta.

Togli il commento dalla printf ed esegui di nuovo per vedere il ciclo costruire la sua risposta. Tracciare con le stampe non è elegante, ma in C è veloce e funziona sempre: un debugger ti dice di più, una printf ti dice qualcosa subito.

Due abitudini evitano che diventi un disastro. Cancella il codice commentato prima del commit; il controllo di versione ricorda la versione vecchia, così non devi farlo tu. E quando lasci di proposito una riga disattivata, spiega il perché in una nota accanto.

Commenti di documentazione

Un commento a blocco sopra una funzione è il posto dove spiegare cosa fa, cosa significano i suoi parametri e qualsiasi cosa sorprendente che la riguardi.

Strumenti come Doxygen leggono commenti strutturati come questi e generano documentazione di riferimento. Lo stile proprio di Doxygen usa /** ... */ con i tag @param e @return:

/**
 * Converte Celsius in Fahrenheit.
 * @param c temperatura in Celsius
 * @return la stessa temperatura in Fahrenheit
 */
double celsius_to_fahrenheit(double c);

Per il tuo codice vanno bene entrambi. Quello che conta è che il commento stia accanto alla dichiarazione che le persone leggono, di solito nel file header, invece di essere sepolto nell'implementazione.

Cosa vale la pena commentare

La regola che sopravvive al contatto con le codebase reali: commenta il perché, non il cosa.

i++;  // incrementa i          <- non dice nulla che il codice non dicesse già
/* Salta il BOM: i file esportati dal vecchio sistema iniziano con
   tre byte che non fanno parte dei dati. */
offset += 3;

Il secondo commento contiene un'informazione che nel codice non c'è da nessuna parte. Il primo è rumore che prima o poi contraddirà la riga che descrive, perché i commenti non vengono aggiornati quando il codice cambia.

Cose che in C valgono davvero un commento:

  • Chi possiede questa memoria. Se una funzione restituisce un puntatore che il chiamante deve liberare con free, dillo. Il C non ha modo di esprimerlo nel tipo.
  • Unità e intervalli. int timeout; è ambiguo: secondi o millisecondi?
  • Correttezza non ovvia. Perché il ciclo si ferma a n - 1, perché questo cast è sicuro, perché il buffer è di 256 byte.
  • Stranezze volute. Il codice che sembra un bug ma non lo è attira "correzioni" da chi lo leggerà in futuro, a meno che non sia segnalato.

Quel commento si guadagna il suo posto: la riga sotto sembra ridondante e non lo è.

I commenti dentro le stringhe non sono commenti

Un ultimo dettaglio. I marcatori di commento non hanno alcun significato speciale dentro una stringa letterale o una costante carattere:

Entrambe le righe vengono stampate per intero. Il compilatore suddivide le stringhe in token prima di cercare i commenti, quindi // tra virgolette sono semplicemente due caratteri. (Il %% nella prima riga è il modo per stampare un simbolo di percentuale letterale con printf: % da solo inizia uno specificatore di formato.)

Domande frequenti

Come si scrive un commento in C?

In due modi. // this is a comment arriva fino alla fine della riga. /* this is a comment */ può occupare un numero qualsiasi di righe e termina al */ di chiusura. Entrambi vengono rimossi prima della compilazione, quindi non influiscono mai sul programma.

C supporta i commenti //?

Sì, da C99. Sono stati presi in prestito dal C++ e oggi sono supportati ovunque. Solo i compilatori C89 davvero antichi li rifiutano, ed è per questo che il codice molto vecchio usa /* */ per tutto, anche per i commenti di una riga.

Si possono annidare i commenti in C?

No. /* outer /* inner */ still outer */ termina al primo */, lasciando still outer */ come codice non valido. Per disattivare un blocco che contiene già commenti /* */, usa invece #if 0 ... #endif, che si annida correttamente.

Come si commenta un blocco di codice in C?

Racchiudilo in /* */ se non contiene commenti a blocco, oppure metti // davanti a ogni riga. L'opzione robusta per regioni grandi è #if 0 prima e #endif dopo: il preprocessore rimuove tutto quello che sta in mezzo, e funziona anche con commenti e virgolette all'interno.

Illustrazione dei linguaggi di programmazione di Coddy

Impara a programmare con Coddy

INIZIA