Perché le persone usano così tanto __ (doppio trattino basso) in C ++


93

Stavo dando uno sguardo al codice C ++ open source e ho notato un sacco di doppi punteggi nei punti in cui vengono utilizzati nel codice, principalmente all'inizio dei nomi delle variabili.

return __CYGWIN__;

Mi chiedo solo se c'è una ragione per questo, o sono solo alcuni stili di codice? Penso che lo renda difficile da leggere.


2
Perché è difficile leggere? È progettato principalmente come un delimetro, proprio come le virgolette. Come ricordo, è utilizzato principalmente per le costanti incorporate.
Matthew Scharley,

1
No, non è un delimitatore. I trattini bassi vengono utilizzati per distinguere i nomi riservati per l'implementazione dai nomi che possono essere utilizzati dal codice sorgente degli utenti. Gli utenti possono fare #define FOO 1ma non devono farlo #define __FOO__ 1e quindi l'implementazione è libera di usare il nome __FOO__per le proprie macro, variabili, funzioni ecc.
Jonathan Wakely

Penso che Matthew volesse dire che è stilisticamente / visivamente un delimetro, non funzionalmente. Che è un'ipotesi interessante, ma errata visto quanto ho letto in precedenza e la risposta di Jonathan.
JMI MADISON

Risposte:


127

Dalla programmazione in C ++, regole e consigli :

L'uso di due trattini bassi (`__ ') negli identificatori è riservato all'uso interno del compilatore secondo lo standard ANSI-C.

I caratteri di sottolineatura ("_") vengono spesso utilizzati nei nomi delle funzioni di libreria (come "_main" e "_exit"). Per evitare collisioni, non iniziare un identificatore con un trattino basso.


1
Sembra che la guida sia stata scritta prima di namespaceessere introdotta.
cz

proveniva anche dall'imperial college london non dallo standard C ++; può essere un buon suggerimento.
stucash

1
Gli spazi dei nomi @cz sono irrilevanti. Un'intestazione di sistema potrebbe definire un nome di macro che inizia con un trattino basso, ad es _main.
martinkunev

49

A meno che non sentano di essere "parte dell'implementazione", cioè le librerie standard, allora non dovrebbero.

Le regole sono abbastanza specifiche e sono leggermente più dettagliate di quanto altri abbiano suggerito.

Tutti gli identificatori che contengono un doppio trattino basso o che iniziano con un trattino basso seguito da una lettera maiuscola sono riservati per l'uso dell'implementazione in tutti gli ambiti, cioè potrebbero essere usati per le macro.

Inoltre, tutti gli altri identificatori che iniziano con un trattino basso (cioè non seguito da un altro carattere di sottolineatura o da una lettera maiuscola) sono riservati per l'implementazione nell'ambito globale. Ciò significa che puoi utilizzare questi identificatori nei tuoi spazi dei nomi o nelle definizioni di classe.

Questo è il motivo per cui Microsoft utilizza i nomi delle funzioni con un trattino basso iniziale e tutti in minuscolo per molte delle loro funzioni di libreria di runtime di base che non fanno parte dello standard C ++. È garantito che questi nomi di funzione non entrino in conflitto con le funzioni C ++ standard o con le funzioni del codice utente.


1
In C ++ vedo solo [lex.name] e per i nomi globali [global.names]. Puoi fornire referenze? grazie
a.lasram

36

Secondo lo standard C ++, gli identificatori che iniziano con un trattino basso sono riservati alle librerie. Gli identificatori che iniziano con due trattini bassi sono riservati ai fornitori di compilatori.


18
Di più: gli identificatori che contengono un doppio trattino basso in qualsiasi punto sono riservati. 17.4.3.1.2
Steve Jessop,

In C ++ vedo solo [lex.name] e per i nomi globali [global.names]. Puoi fornire referenze? grazie
a.lasram

10

I commenti precedenti sono corretti. __Symbol__è generalmente un token magico fornito dal tuo utile fornitore di compilatore (o preprocessore). Forse i più usati di questi sono __FILE__e __LINE__, che vengono espansi dal preprocessore C per indicare il nome del file corrente e il numero di riga. È utile quando si desidera registrare una sorta di errore di asserzione del programma, inclusa la posizione testuale dell'errore.


8

È qualcosa che non dovresti fare in un codice "normale". Ciò garantisce che i compilatori e le librerie di sistema possano definire simboli che non entreranno in conflitto con i tuoi.


4

I doppi trattini bassi sono riservati all'implementazione

La risposta più votata cita Programmazione in C ++: regole e consigli :

"L'uso di due trattini bassi (` __ ') negli identificatori è riservato all'uso interno del compilatore secondo lo standard ANSI-C. "

Tuttavia, dopo aver letto alcuni standard C ++ e C, non sono riuscito a trovare alcuna menzione di trattini bassi limitati solo all'uso interno del compilatore. Gli standard sono più generali, riservando doppi trattini bassi per l'implementazione .

C ++

C ++ (attuale bozza di lavoro, accesso 2019-5-26) afferma in lex.name:

  • Ogni identificatore che contiene un doppio trattino basso __ o inizia con un trattino basso seguito da una lettera maiuscola è riservato all'implementazione per qualsiasi uso.
  • Ogni identificatore che inizia con un trattino basso è riservato all'implementazione per essere utilizzato come nome nello spazio dei nomi globale.

C

Sebbene questa domanda sia specifica per C ++, ho citato sezioni pertinenti degli standard C 99 e 17:

C99 sezione 7.1.3

  • Tutti gli identificatori che iniziano con un trattino basso e una lettera maiuscola o un altro trattino basso sono sempre riservati per qualsiasi uso.
  • Tutti gli identificatori che iniziano con un trattino basso sono sempre riservati per essere utilizzati come identificatori con ambito di file sia negli spazi dei nomi ordinari che in quelli dei tag.

C17 dice la stessa cosa di C99.

Qual è l'implementazione ?

Per C / C ++, l' implementazione si riferisce vagamente alle risorse impostate necessarie per produrre un eseguibile dai file di origine dell'utente. Ciò comprende:

  • preprocessore
  • compilatore
  • linker
  • libreria standard

Implementazioni di esempio

Ci sono un certo numero di diverse implementazioni C ++ menzionate su Wikipedia . (nessun link di ancoraggio, ctrl + f "implementazione")

Ecco un esempio di implementazione C / C ++ di Digital Mars riservando alcune parole chiave per una loro funzionalità.


3

Oltre alle librerie su cui molte altre persone hanno risposto, alcune persone nominano anche macro o valori #define da utilizzare con il preprocessore. Ciò renderebbe più facile lavorare con e potrebbe aver permesso di aggirare i bug nei vecchi compilatori.

Come altri menzionati, aiuta a prevenire la collisione di nomi e aiuta a delineare tra le variabili della libreria e le tue.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.