web-dev-qa-db-ja.com

Cの一部の関数にアンダースコアプレフィックスが付いているのはなぜですか?

私は最近Cでネットワーキングを学び始め、_function()のようなアンダースコアで始まるいくつかの関数を見ました-それは正確にはどういう意味ですか?私もこれを見ました:

 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)];  

};

コードのこの部分はどういう意味ですか:

__SOCKADDR_COMMON (sin_);

unsigned char sin_zero[sizeof (struct sockaddr) - 

 __SOCKADDR_COMMON_SIZE -  

sizeof (in_port_t) -         

sizeof (struct in_addr)];
11
pedro santos

アンダースコアプレフィックスは、コンパイラと標準ライブラリで使用される関数とタイプ用に予約されています。これらの名前は正しいユーザープログラムと競合しないため、標準ライブラリは自由にこれらの名前を使用できます。

これの反対側は、アンダースコアで始まる名前を定義することは許可されていないということです。

さて、それがルールの要点です。実際のルールはこれです:

  • 名前がアンダースコアで始まるグローバルスコープの識別子は、非表示の(プライベート)ライブラリ定義と競合する可能性があるため、定義できません。したがって、これはコードでは無効です。

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

    しかし、これは有効です:

    #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
    
  • 名前が2つのアンダースコアで始まる、または1つのアンダースコアの後に大文字が続くスコープ内の識別子を定義することはできません。したがって、これは無効です。

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

    しかし、これは大丈夫です:

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

物事を複雑にするために、実際にはさらにいくつかのルールがありますが、上記のルールは最も頻繁に違反され、覚えるのが最も簡単です。

18
Dietrich Epp

先頭の下線は通常、次の3つのいずれかを示します。

  1. 定義はC標準の一部ではないため、移植性はありません
  2. 定義はライブラリまたはコンパイラの内部にあり、外部からは使用しないでください
  3. この定義は、追加の知識を必要とするリスクまたは必要な構成を意味するため、軽く使用しないでください。

この場合、__SOCKADDR_COMMONは(2)です。通常はユーザーランドからアクセスするstruct sockaddr_inタイプの一部である内部定義です。

5
slezica