2017-09-17 8 views
-1

のgetaddrinfoの定義は()である:なぜgetaddrinfo()は関数の入力部分の値を返しますか?

int getaddrinfo(const char *node,  // e.g. "www.example.com" or IP 
       const char *service, // e.g. "http" or port number 
       const struct addrinfo *hints, 
       struct addrinfo **res); 

パーBeejのsiteそれは言う:

「、解像度、あなたがこの機能に3つの入力パラメータを与え、そしてそれはあなたのリンクリストへのポインタを与えます結果の。

使用量の面では、次のとおりです。

if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) { 
    fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); 
    return 1; 
} 

// loop through all the results and bind to the first we can 
for(p = servinfo; p != NULL; p = p->ai_next) { 
    if ((sockfd = socket(p->ai_family, p->ai_socktype, 
      p->ai_protocol)) == -1) { 
     perror("server: socket"); 
     continue; 
    } 

    if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, 
      sizeof(int)) == -1) { 
     perror("setsockopt"); 
     exit(1); 
    } 

    if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) { 
     close(sockfd); 
     perror("server: bind"); 
     continue; 
    } 

    break; 
} 

実際の戻り値「rv」は、実際に使用されることはありません。しかし、結果は第4入力 "res"またはこの例の "servinfo"から取られます。私は、リンクされたリストが関わっていることを理解していますが、関数の戻り値が通常の方法で動作しない理由は明らかではありません。なぜ "rv"はアドレスを取得するために反復される配列ではないのですか?入力が結果を返すのはなぜですか?

+2

非常によく見ると、第2行目で 'rv'が実際に使用されています。それが 'gai_seterror'に渡されたときに、エラーメッセージをユーザにフォーマットして、呼び出しが失敗した理由を示します。 – selbie

+0

C *で参照渡しをエミュレートする方法についていくつかの調査を行います。 –

+0

サードパーティのサイトを参照として引用することはできません。あなたは* man * pageに相談することを検討しましたか? – EJP

答えて

2

rvは、です。操作が成功した場合は0、失敗した場合はエラーコードが含まれます。質問で提供したサンプルコードでrvが使用されていることさえあります。

            // ↓ result is compared to 0 
if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) { 
    fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); 
                // ↑ error message based on rv 
    return 1; 
} 

Cは複数の戻り値を持つ関数をサポートしていません。複数の出力を持つgetaddrinfo()のような関数では、少なくとも1つの出力をポインタとして関数に渡す必要があります。

また、構造体がgetaddrinfo()の結果を含むように定義されている可能性もありますが、それはちょっと面倒です。

1

関数のコード化方法は、関数が正常に実行されたかどうかにかかわらず、戻り値はステータスコードに過ぎないということです。次に、より複雑な結果セットが、提供されたリンク・リスト・ポインターに取り込まれます。

Cでこのようなことをするのは珍しいことではありません。** res表記は確かに紛らわしいですが、関数がjavaに空のLinkedListオブジェクトを与えて関数がそれを埋め込むのと同じです。

合計でCに - これは珍しいことではありません。そして、入力が値ではなく参照/ポインタによって渡されたとき、それを得る関数は、それが望むようにそれを行うことができます。他の言語でもそうです。

関連する問題