6

Cライブラリのソケットインターフェイスのコードを読んで、私はこれを見つけました:

/* Types of sockets.  */
enum __socket_type
{
   SOCK_STREAM = 1,     /* Sequenced, reliable, connection-based
               byte streams.  */
#define SOCK_STREAM SOCK_STREAM
   SOCK_DGRAM = 2,      /* Connectionless, unreliable datagrams
               of fixed maximum length.  */
#define SOCK_DGRAM SOCK_DGRAM
...

この「イディオム」は、bits/socket.h全体で使用されます。私はただ興味があります、それらのマクロの目的は何ですか?

4

3 に答える 3

7

これらの定数は以前は#definesでした。したがって、表示されているのは、古いヘッダーファイルと新しいヘッダーファイルが誤って混在するのを防ぐためです。enum定数を定義するために使用する利点は、enumメンバーがデバッガーで使用可能になる傾向があり、#defineマクロは使用できないことです。

(誤って)他のヘッダーファイルをインクルードしようとすると#define SOCK_STREAM、誤った値を黙って使用するのではなく、コンパイラの警告が表示されます。

アップデート

glibc gitリポジトリを調べてみると、sを追加した特定のコミットが見つかりました#define。このコメントは次のとおりです。

* sysdeps/generic/socketbits.h: Also make SOCK_* constants available
as macros so that #ifdef works.
* sysdeps/unix/sysv/linux/socketbits.h: Likewise.

そこにあります。

于 2012-07-09T04:53:53.427 に答える
1

これは、「列挙型」に相当するCです。

論理ソケットタイプ「ストリーム」(SOCK_STREAM)は、バイナリ値「1」に対応します。「データグラム」(SOCK_DGRAM)はタイプ「2」です。等。

「ソケット」は、「列挙型」がC言語の一部になる前に発明されました。

上記のイディオムを使用すると、コードで「SOCK_STREAM」(たとえば)を使用できます。また、「#ifndef SOCK_STREAM」(一部のレガシープログラムでは重要な場合があります)を使用することもできます。

于 2012-07-09T04:53:09.683 に答える
0

歴史的なシステムはマクロを使用し、そのような列挙型を持っていませんでした。

古いバージョンのPOSIX/Single Unix(SUSv3などSOCK_xxx)では、マクロであることが義務付けられていました。これは、これらの定数がプリプロセッサディレクティブで使用できることを意味します(例#ifdef SOCK_DGRAM)。これは、システムが非標準のソケットタイプをサポートしているかどうかをビルド時に確認するのに役立つ場合があります。

新しい標準(SUSv4など)では、システムに対するこの要件が緩和されています。SOCK_xxx定数は、任意の種類のシンボリック定数にすることができます。これには、プリプロセッサマクロだけでなく、列挙型定数など、定数式(静的初期化子や定数式を必要とするその他のコンテキストに適しています)を生成するその他の種類の定義も含まれます。

あなたが見ている実装はSUSv3に準拠しています(そしてSUSv4、SUSv3準拠はこの点でSUSv4準拠を意味します)。列挙型のみを定義し、定数は定義しない実装は、SUSv4に準拠しますが、SUSv3には準拠しません。

SOCK_xxx列挙型を定義する利点は、定数を呼び出さないコンテキストで定数が使用されている場合、またはSOCK_xxx値が期待される場所で任意の整数が使用されている場合に、コンパイラーが適切なフィードバックを提供できることです。

同じことが多くの同様の定数のセットにも当てはまります。

于 2016-09-21T21:54:11.297 に答える