Pergunta

extern int ether_hostton (__const char *__hostname, struct ether_addr *__addr)
 __THROW;

Eu encontrei a definição da função acima em /usr/include/netinet/ether.h em uma caixa de Linux.

Alguém pode explicar o que os sublinhados duplos significam na frente de const (keyword), addr (identificador) e no último __THROW.

Foi útil?

Solução

C, símbolos começando com um sublinhado seguido por uma letra maiúscula ou outro sublinhado são reservados para a aplicação. Você, como um usuário de C não deve criar quaisquer símbolos que começam com as seqüências reservadas. Em C ++, a restrição é mais rigorosa; você o usuário não pode criar um símbolo contendo um duplo sublinhado.

Dada:

extern int ether_hostton (__const char *__hostname, struct ether_addr *__addr)
__THROW;

A notação __const está lá para permitir a possibilidade (pouco provável) que um compilador que este código é utilizado com suportes protótipo notações, mas não tem uma compreensão correta do C89 const palavra-chave padrão. As macros autoconf ainda pode verificar se o compilador tem suporte trabalhando para const; este código pode ser usado com um compilador quebrado que não tem esse apoio.

O uso de __hostname e __addr é uma medida de proteção para você, o usuário do cabeçalho. Se você compilar com GCC ea opção -Wshadow, o compilador irá avisá-lo quando todas as variáveis ??locais sombra uma variável global. Se a função usada apenas hostname vez de __hostname, e se você tivesse uma função chamada hostname(), haveria um sombreamento. Ao usar nomes reservados para a implementação, não há nenhum conflito com o seu código legítimo.

A utilização de meios __THROW que o código pode, em algumas circunstâncias, ser declarado com algum tipo de 'especificação lance'. Este não é o padrão C; é mais como C ++. Mas o código pode ser usado com um compilador C, desde que um dos cabeçalhos (ou o próprio compilador) define __THROW para esvaziar, ou a alguma extensão específica do compilador da sintaxe C padrão.


Secção 7.1.3 do padrão C (ISO 9899: 1999) diz:

7.1.3 reservados identificadores

Cada cabeçalho declara ou define todos os identificadores listados em seu subitem associado, e opcionalmente declara ou define identificadores listados em seus futuros associados instruções Library subitem e identificadores que são sempre reservadas, quer para qualquer uso ou para uso como arquivo identificadores de escopo.

- Todos os identificadores que começam com um sublinhado e quer uma letra maiúscula ou de outra 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 do arquivo em ambos os espaços de nomes comuns e tag.

- Cada nome de macro em qualquer um dos seguintes subseções (incluindo a biblioteca futuro instruções) é reservada para uso como especificado se qualquer um de seus cabeçalhos associados está incluída; salvo indicação em contrário (ver 7.1.4).

- Todos os identificadores com ligação externa em qualquer uma das seguintes subseções (incluindo o instruções Library futuro) são sempre reservados para uso como identificadores com externo ligação. 154)

- Cada identificador com escopo do arquivo listado em qualquer um dos seguintes subseções (incluindo o instruções Library futuro) é reservado para uso como um nome de macro e como um identificador com escopo do arquivo no mesmo espaço de nome, se qualquer um dos seus cabeçalhos associados está incluído.

Não há outros identificadores são reservados. Se o programa declara ou define um identificador em um contexto em que é reservado (excepto conforme permitido pela 7.1.4), ou define uma reservada identificador como um nome de macro, o comportamento é indefinido.

Se os remove do programa (com #undef) qualquer definição de macro de um identificador no primeiro grupo listado acima, o comportamento é indefinido.

Nota de rodapé 154) A lista de identificadores reservados com ligação externa inclui errno, math_errhandling, setjmp e va_end.


Veja também Quais são as regras sobre o uso de um sublinhado em um C ++ identificador , um monte das mesmas regras se aplicam a ambos C e C ++, embora a regra da dupla sublinhado incorporado está em C ++ apenas, como mencionado no início desta resposta.

Outras dicas

Nomes com sublinhados principais duplas são reservados para uso pela implementação. Isso não significa necessariamente que eles são internos per se, embora muitas vezes eles são.

A idéia é, você não tem permissão para usar quaisquer nomes começando com __, de modo a implementação é livre para usá-los em lugares como expansões de macro, ou nos nomes de extensões de sintaxe (por exemplo __gcnew não faz parte do C ++ , mas a Microsoft pode adicioná-lo para C ++ / CLI confiante de que nenhum código existente deve ter algo parecido int __gcnew; em que ela iria parar de compilar).

Para descobrir o que essas extensões específicas dizer, ou seja __const você precisará consultar a documentação do seu compilador específico plataforma /. Neste caso particular, você provavelmente deve considerar o protótipo na documentação (por exemplo, http://www.kernel.org/doc/man-pages/online/pages/man3/ether_aton.3.html ) para ser a interface do função e ignorar os __const e __THROW decorações que aparecer no cabeçalho real.

Por convenção em algumas bibliotecas, isso indica que um símbolo específico é para uso interno e não se destina a ser parte da API pública da biblioteca.

O sublinhado no meio __const que esta palavra-chave é uma extensão do compilador e usá-lo não é portátil (A palavra-chave const foi adicionado em C em uma revisão posterior, 89 eu acho). O __THROW também é uma espécie de extensão, presumo que ele seja definido para alguns __attribute __ (algo) se gcc é usado, mas não tenho certeza sobre isso e com preguiça de verificar. O __addr pode significar qualquer coisa que o programador queria que dizer, é apenas um nome.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top