58 votes

Que signifie le double soulignement (__const) en C?

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

J'ai trouvé la définition de fonction ci-dessus dans /usr/include/netinet/ether.h sur une boîte Linux.

Quelqu'un peut-il expliquer ce que signifient les doubles soulignés devant const (mot-clé), addr (identifiant) et enfin __THROW.

81voto

Jonathan Leffler Points 299946

En C, les symboles commençant par un caractère de soulignement suivi par une lettre majuscule ou un autre trait de soulignement sont réservés pour la mise en œuvre. Vous en tant qu'utilisateur de C ne doit pas créer des symboles qui commencent avec la réserve de séquences. En C++, la restriction est plus rigoureux; vous, l'utilisateur ne peut pas créer un symbole contenant un double trait de soulignement.

Donnée:

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

L' __const notation est là pour permettre la possibilité (peu probable) qu'un compilateur que ce code est utilisé avec des supports prototype de notations, mais n'ont pas une compréhension correcte de la norme C89 mot-clé const. L' autoconf macros peuvent toujours vérifier si le compilateur a le support pour const; ce code peut être utilisé avec une fracture du compilateur qui n'ont pas de soutien.

L'utilisation de l' __hostname et __addr est une mesure de protection pour vous, l'utilisateur de l'en-tête. Si vous compiler avec GCC et de l' -Wshadow option, le compilateur va vous avertir lorsque des variables locales à l'ombre d'une variable globale. Si la fonction utilisée juste hostname au lieu de __hostname, et si vous aviez une fonction appelée hostname(), il y aurait une répétition. En utilisant des noms réservés à la mise en œuvre, il n'y a pas de conflit avec votre code légitime.

L'utilisation de l' __THROW signifie que le code peut, dans certaines circonstances, être déclaré avec une certaine forme de "jeter specification". Ce n'est pas la norme C; il est plus comme le C++. Mais le code peut être utilisé avec un compilateur C aussi longtemps que l'un des en-têtes (ou le compilateur lui-même) définit __THROW de vide, ou à un compilateur spécifique à l'extension de la norme C syntaxe.


Section 7.1.3 de la norme (ISO 9899:1999) dit:

7.1.3 identificateurs Réservés

Chaque en-tête déclare ou définit l'ensemble des identifiants dans la subdivision, et éventuellement déclare ou définit identifiants dans son futur associé de la bibliothèque directions la subdivision et les identificateurs qui sont toujours réservées pour toute utilisation ou pour une utilisation en tant que fichier la portée des identificateurs.

- Tous les identificateurs commençant par un trait de soulignement et une lettre majuscule ou un autre trait de soulignement sont toujours réservés pour toute utilisation.

- Tous les identificateurs commençant par un caractère de soulignement sont toujours réservés pour une utilisation en tant qu'identifiants avec le fichier de la portée à la fois l'ordinaire et le nom de la balise espaces.

- Chaque nom de la macro dans l'une des subdivisions (y compris la future bibliothèque les directions) est réservé pour une utilisation comme spécifié si l'un de ses associés en-têtes est inclus; sauf mention explicite contraire (voir 7.1.4).

- Tous les identificateurs de liaison externe dans l'une des subdivisions (y compris les avenir de la bibliothèque directions) sont toujours réservés pour une utilisation en tant qu'identifiants externes de liaison.154)

- Chaque identifiant à la portée de fichier répertoriés dans l'une des subdivisions (y compris les avenir de la bibliothèque de sens) est réservé pour une utilisation en tant que nom de la macro et comme un identificateur avec la portée du fichier dans le même espace de nom si l'un de ses associés en-têtes est inclus.

Pas d'autres identifiants sont réservés. Si le programme déclare ou définit un identificateur dans un contexte dans lequel il est réservé (autres que celles autorisées par 7.1.4), ou de définir une réservés identificateur de nom de la macro, le comportement est indéfini.

Si le programme supprime (avec #undef) toute définition de macro d'un identifiant dans la première groupe énumérés ci-dessus, le comportement est indéfini.

Note de bas de page 154) La liste des identificateurs réservés avec une liaison externe inclut errno, math_errhandling, setjmp, et va_end.


Voir aussi Quelles sont les règles concernant l'utilisation d'un trait de soulignement dans un C++ identifiant; un grand nombre des mêmes règles s'appliquent à la fois le C et le C++, bien que l'embedded double-trait de soulignement de la règle est en C++ uniquement, comme indiqué en haut de cette réponse.

19voto

Logan Capaldo Points 22145

Noms avec double principaux traits de soulignement sont réservés pour une utilisation par la mise en œuvre. Cela ne veut pas nécessairement dire qu'ils sont à l'intérieur de soi, bien qu'ils soient souvent.

L'idée est, vous n'êtes pas autorisé à utiliser tous les noms commençant par __, de sorte que la mise en œuvre est libre de les utiliser dans des endroits comme l'expansion des macros, ou dans les noms des extensions de syntaxe (par exemple, __gcnew n'est pas une partie de C++, mais Microsoft peut ajouter à C++/CLI convaincue qu'aucun code existant devriez avoir quelque chose comme int __gcnew; en ce qui permettrait d'arrêter la compilation).

Pour trouver ces extensions spécifiques veux dire, c'est à dire __const vous aurez besoin de consulter la documentation de votre compilateur/plate-forme. Dans ce cas particulier, vous devriez probablement envisager le prototype dans la documentation (p. ex. http://www.kernel.org/doc/man-pages/online/pages/man3/ether%5Faton.3.html) à la fonction d'interface et d'ignorer l' __const et __THROW décorations qui apparaissent dans l'en-tête.

3voto

Rob H Points 5599

Par convention dans certaines bibliothèques, cela indique qu'un symbole particulier est à usage interne et n'est pas destiné à faire partie de l'API publique de la bibliothèque.

2voto

Caotic Points 686

Le trait de soulignement dans __const signifie que ce mot clé est une extension du compilateur et que son utilisation n'est pas portable (le mot clé const a été ajouté à C dans une révision ultérieure, 89 je pense). Le __THROW est aussi une sorte d'extension, je suppose qu'il est défini sur un __attribute __ (quelque chose) si gcc est utilisé, mais je ne suis pas sûr à ce sujet et trop paresseux pour vérifier. Le __addr peut signifier tout ce que le programmeur voulait qu'il signifie, c'est juste un nom.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X