Por que as pessoas usam tanto __ (sublinhado duplo) em C ++

93

Eu estava dando uma olhada em alguns códigos C ++ de código aberto e percebi que muitas pontuações duplas eram usadas no código, principalmente no início dos nomes de variáveis.

return __CYGWIN__;

Apenas me perguntando se há uma razão para isso ou são apenas alguns estilos de código de pessoas? Eu acho que o torna difícil de ler.

Nathan W
fonte
2
Por que é difícil de ler? Ele é projetado principalmente como um delimitador, assim como as citações. Pelo que me lembro, ele é usado principalmente para constantes embutidas.
Matthew Scharley,
1
Não, não é um delimitador. Os sublinhados são usados ​​para distinguir nomes reservados para a implementação de nomes que o código-fonte dos usuários pode usar. Os usuários podem fazer, #define FOO 1mas não devem fazer #define __FOO__ 1e, portanto, a implementação é livre para usar o nome __FOO__para suas próprias macros, variáveis, funções, etc.
Jonathan Wakely
Acho que Matthew quis dizer que é estilisticamente / visualmente um delimitador, não funcionalmente. O que é uma hipótese interessante, mas incorreta, considerando o que li anteriormente e a resposta de Jonathan.
JMI MADISON

Respostas:

127

De Programação em C ++, Regras e Recomendações :

O uso de dois sublinhados (`__ ') em identificadores é reservado para uso interno do compilador de acordo com o padrão ANSI-C.

Os sublinhados (`_ ') são freqüentemente usados ​​em nomes de funções de biblioteca (como" _main "e" _exit "). Para evitar colisões, não comece um identificador com um sublinhado.

maccullt
fonte
1
Esse guia parece ter sido escrito antes de namespaceser apresentado.
cz
era também do Imperial College de Londres, não do padrão C ++; pode ser uma boa sugestão.
stucash de
1
Os namespaces @cz são irrelevantes. Um cabeçalho do sistema pode definir um nome de macro que começa com sublinhado, por exemplo _main.
martinkunev de
49

A menos que eles sintam que são "parte da implementação", ou seja, as bibliotecas padrão, eles não deveriam.

As regras são bastante específicas e ligeiramente mais detalhadas do que algumas outras sugeriram.

Todos os identificadores que contêm um sublinhado duplo ou começam com um sublinhado seguido por uma letra maiúscula são reservados para o uso da implementação em todos os escopos, ou seja, podem ser usados ​​para macros.

Além disso, todos os outros identificadores que começam com um sublinhado (ou seja, não seguidos por outro sublinhado ou uma letra maiúscula) são reservados para a implementação no escopo global. Isso significa que você pode usar esses identificadores em seus próprios namespaces ou nas definições de classe.

É por isso que a Microsoft usa nomes de função com um sublinhado inicial e todos em minúsculas para muitas de suas principais funções de biblioteca de tempo de execução que não fazem parte do padrão C ++. Esses nomes de função têm a garantia de não entrar em conflito com as funções C ++ padrão ou funções de código do usuário.

CB Bailey
fonte
1
Em C ++, vejo apenas [lex.name] e para nomes globais [global.names]. Você pode dar referências? obrigado
a.lasram
36

De acordo com o padrão C ++, os identificadores que começam com um sublinhado são reservados para bibliotecas. Identificadores que começam com dois sublinhados são reservados para fornecedores de compiladores.

James Curran
fonte
18
Mais do que isso: os identificadores que contêm um sublinhado duplo em qualquer lugar deles são reservados. 17.4.3.1.2
Steve Jessop,
Em C ++, vejo apenas [lex.name] e para nomes globais [global.names]. Você pode dar referências? obrigado
a.lasram
10

Os comentários anteriores estão corretos. __Symbol__geralmente é um token mágico fornecido por seu fornecedor de compilador (ou pré-processador) útil. Talvez os mais usados ​​sejam __FILE__e __LINE__, que são expandidos pelo pré-processador C para indicar o nome do arquivo atual e o número da linha. Isso é útil quando você deseja registrar algum tipo de falha de declaração do programa, incluindo a localização textual do erro.

pântano
fonte
8

É algo que você não deve fazer no código 'normal'. Isso garante que os compiladores e as bibliotecas do sistema possam definir símbolos que não colidam com os seus.

Menkboy
fonte
4

Os sublinhados duplos são reservados para a implementação

A resposta mais votada cita Programação em C ++: Regras e Recomendações :

"O uso de dois sublinhados (` __ ') em identificadores é reservado para uso interno do compilador de acordo com o padrão ANSI-C. "

No entanto, depois de ler alguns padrões C ++ e C, não consegui encontrar nenhuma menção de sublinhados sendo restritos apenas ao uso interno do compilador. Os padrões são mais gerais, reservando sublinhados duplos para a implementação .

C ++

C ++ (rascunho de trabalho atual, acessado em 26/05/2019) afirma em lex.name:

  • Cada identificador que contém um sublinhado duplo __ ou começa com um sublinhado seguido por uma letra maiúscula é reservado para a implementação para qualquer uso.
  • Cada identificador que começa com um sublinhado é reservado para a implementação para uso como um nome no namespace global.

C

Embora esta questão seja específica para C ++, eu citei seções relevantes dos padrões C 99 e 17:

C99 seção 7.1.3

  • Todos os identificadores que começam com um sublinhado e uma letra maiúscula ou outro sublinhado são sempre reservados para qualquer uso.
  • Todos os identificadores que começam com um sublinhado são sempre reservados para uso como identificadores com escopo de arquivo nos espaços de nomes comuns e de tag.

C17 diz a mesma coisa que C99.

Qual é a implementação ?

Para C / C ++, a implementação refere-se vagamente aos recursos definidos necessários para produzir um executável a partir dos arquivos de origem do usuário. Isso inclui:

  • pré-processador
  • compilador
  • vinculador
  • biblioteca padrão

Implementações de exemplo

Existem várias implementações C ++ diferentes mencionadas na Wikipedia . (sem link de âncora, ctrl + f "implementação")

Aqui está um exemplo de implementação C / C ++ da Digital Mars reservando algumas palavras-chave para um recurso deles.

RemarkableBucket
fonte
3

Além das bibliotecas sobre as quais muitas outras pessoas responderam, algumas pessoas também nomeiam macros ou #define valores para uso com o pré-processador. Isso tornaria mais fácil trabalhar com ele e pode ter permitido que bugs em compiladores mais antigos fossem contornados.

Como outros mencionados, ajuda a evitar colisão de nomes e ajuda a delinear entre as variáveis ​​da biblioteca e as suas.

Sqeaky
fonte