Pourquoi certaines fonctions en C ont-elles un préfixe de soulignement?

J’ai récemment commencé à apprendre le réseautage en C et j’ai vu certaines fonctions commençant par une fonction _ comme _ (-) (qu’est-ce que cela signifie exactement? J’ai aussi vu ceci:

struct sockaddr_in { __SOCKADDR_COMMON (sin_); in_port_t sin_port; struct in_addr sin_addr; unsigned char sin_zero[sizeof (struct sockaddr) - __SOCKADDR_COMMON_SIZE - sizeof (in_port_t) - sizeof (struct in_addr)]; }; 

que signifie cette partie du code:

 __SOCKADDR_COMMON (sin_); unsigned char sin_zero[sizeof (struct sockaddr) - __SOCKADDR_COMMON_SIZE - sizeof (in_port_t) - sizeof (struct in_addr)]; 

    Le préfixe de soulignement est réservé aux fonctions et aux types utilisés par le compilateur et la bibliothèque standard. La bibliothèque standard peut utiliser ces noms librement car ils ne seront jamais en conflit avec les programmes utilisateur appropriés.

    Le problème est que vous n’êtes pas autorisé à définir des noms commençant par un trait de soulignement.

    Eh bien, c’est l’essentiel de la règle. La règle actuelle est la suivante:

    • Vous ne pouvez définir aucun identificateur dans la scope globale dont les noms commencent par un trait de soulignement, car ceux-ci peuvent entrer en conflit avec les définitions de bibliothèque masquées (privées). Donc, ceci n’est pas valide dans votre code:

       #ifndef _my_header_h_ #define _my_header_h_ // wrong int _x; // wrong float _my_function(void); // wrong #endif 

      Mais ceci est valable:

       #ifndef my_header_h #define my_header_h // ok int x; // ok float my_function(void) { // ok int _x = 3; // ok in function } struct my_struct { int _x; // ok inside structure }; #endif 
    • Vous ne pouvez définir aucun identifiant dans une scope dont le nom commence par deux traits de soulignement ou un trait de soulignement suivi d’une lettre majuscule. Donc c’est invalide:

       struct my_struct { int _Field; // Wrong! int __field; // Wrong! }; void my_function(void) { int _X; // Wrong! int __y; // Wrong! } 

      Mais c’est bon:

       struct my_struct { int _field; // okay }; void my_function(void) { int _x; // okay } 

    Il existe en fait quelques règles supplémentaires, juste pour rendre les choses plus compliquées, mais les règles ci-dessus sont les plus souvent violées et les plus faciles à retenir.

    Les principaux soulignés indiquent généralement l’une des 3 choses suivantes:

    1. La définition ne fait pas partie de la norme C, elle n’est donc pas portable
    2. La définition est interne à une bibliothèque ou à un compilateur et ne doit pas être utilisée de l’extérieur
    3. La définition ne doit pas être utilisée à la légère car elle implique des risques ou une configuration nécessaire nécessitant des connaissances supplémentaires.

    Dans ce cas, __SOCKADDR_COMMON est (2): une définition interne, qui fait partie du type struct sockaddr_in , à laquelle vous accédez généralement à partir de userland.