web-dev-qa-db-ja.com

getpid()がintではなくpid_tを返すのはなぜですか?

getpid()typeの値を返すpid_tの代わりにunsigned int?またはint?これはどのように役立ちますか?

これは移植性に関係していると思いますか? pid_tは、異なるサイズのintsなどを持つ異なるプラットフォーム間で同じサイズですか?

48
ntl0ve

それは逆だと思います:たとえば、PIDが16ビットか32ビット(またはそれ以上)かどうかに関係なく、プラットフォーム間でプログラムを移植可能にします。

41
zvrba

その理由は、厄介な歴史的な実装がまだ適合していることを許可するためです。あなたの歴史的な実装が(むしろ一般的)を持っていたと仮定します:

short getpid(void);

もちろん、最新のシステムはpidが少なくとも32ビットであることを望んでいますが、標準が義務付けられている場合:

int getpid(void);

shortを使用していたすべての歴史的な実装は不適合になります。これは受け入れられないと見なされたので、pid_tが作成され、実装はpid_tを任意の方法で定義できました。

Pidを格納するのに十分な大きさの型を使用する限り、独自のコードでpid_tを使用する義務はないことに注意してください(たとえば、intmax_tはうまく機能します)。 pid_t必要が存在する唯一の理由は、標準がgetpidwaitpidなどを定義することです。

34
R..

異なるプラットフォームおよびオペレーティングシステムでは、異なるタイプ(pid_tなど)は、32ビットマシンでは32ビット(unsigned int)、64ビットマシンでは64ビット(unsigned long)になります。または、他の何らかの理由で、オペレーティングシステムが異なるサイズを選択する場合があります。さらに、この変数が任意の数字ではなく「オブジェクト」を表すことをコードを読み取るときに明確にします。

9
Maz

その目的は、pid_tまたはその他の種類のプラットフォームをプラットフォームに依存せずに、実際の実装方法に関係なく適切に動作するようにすることです。この方法は、次のようなプラットフォームに依存しないタイプに使用されます。

  • pid_t:コーディング対象のシステムにPIDを格納するのに十分な大きさが必要です。私が知っている限り、intにマップしますが、私はGNU Cライブラリに精通していません。
  • size_tunsigned演算子の結果を格納できるsizeof変数。通常、サイズはコーディング対象のシステムのWordサイズと同じです。
  • int16_tintX_t):プラットフォームに関係なく、正確に16ビットである必要があり、2を使用しないプラットフォームでは定義されませんn-ビットバイト(通常8または16ビット)、またははるかに少ない頻度で、より大きなタイプのうち正確に16ビットにアクセスする手段を提供します(たとえば、PDP-10の「バイト」は任意の数の連続したビットです) 36ビットのWordであるため、正確に16ビットである可能性があります)、したがって、16ビットの2の補数整数型(36ビットシステムなど)をサポートしません。一般的に、最新のコンピューターではshortにマップされますが、古いコンピューターではintになります。
  • int_least32_tint_leastX_t):36ビットまたは72ビットシステムの36ビットなど、少なくとも32ビットを格納できる最小サイズである必要があります。一般に、最新のコンピューターではintにマップされますが、古いコンピューターではlongになります。
  • int_fastX_t:少なくともXビットを格納できる最速のタイプでなければなりません。一般に、(X <= Word_size)(またはint_fast8_tの場合はchar)の場合はシステムのWordサイズ、またはint_leastX_tの場合は(X > Word_size)のように動作します
  • intmax_t:システムでサポートされている最大整数幅でなければなりません。一般に、最新のシステムでは少なくとも64ビットになりますが、一部のシステムはlong longよりも大きい拡張型をサポートする場合があります(そうであれば、intmax_tはこれらの型の中で最大である必要があります)。
  • もっと...

機械的には、適切なヘッダーファイルを作成してコンパイラの実行可能ファイルにコーディングするかどうかに関係なく、コンパイラのインストーラーが裏でtypedef識別子の適切な型(標準型または厄介な名前の内部型)を舞台裏で許可します。 、またはその他の方法。たとえば、32ビットシステムでは、Microsoft Visual StudioはintX_tおよび類似のタイプを次のように実装します(注:私が追加したコメント)。

// Signed ints of exactly X bits.
typedef signed char int8_t;
typedef short int16_t;
typedef int int32_t;

// Unsigned ints of exactly X bits.
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;

// Signed ints of at least X bits.
typedef signed char int_least8_t;
typedef short int_least16_t;
typedef int int_least32_t;

// Unsigned ints of at least X bits.
typedef unsigned char uint_least8_t;
typedef unsigned short uint_least16_t;
typedef unsigned int uint_least32_t;

// Speed-optimised signed ints of at least X bits.
// Note that int_fast16_t and int_fast32_t are both 32 bits, as a 32-bit processor will generally operate on a full Word faster than a half-Word.
typedef char int_fast8_t;
typedef int int_fast16_t;
typedef int int_fast32_t;

// Speed-optimised unsigned ints of at least X bits.
typedef unsigned char uint_fast8_t;
typedef unsigned int uint_fast16_t;
typedef unsigned int uint_fast32_t;

typedef _Longlong int64_t;
typedef _ULonglong uint64_t;

typedef _Longlong int_least64_t;
typedef _ULonglong uint_least64_t;

typedef _Longlong int_fast64_t;
typedef _ULonglong uint_fast64_t;

ただし、64ビットシステムでは、必ずしも同じ方法で実装されるとは限らないため、MSVS互換のバージョンを見つけることができれば、古風な16ビットシステムで同じ方法で実装されないことを保証できます。 1と。

全体的に、実装の仕様に関係なくコードが適切に動作し、標準互換システムで同じ要件を満たすことができます(たとえば、pid_tはシステムで有効なPIDを保持するのに十分な大きさであることが保証されます)対象のシステムに関係なく、問題になります)。それはまた、あなたが核心を知り、あなたがよく知らないかもしれない内部名を調べなければならないことを防ぎます。つまり、pid_t(または他の同様のtypedef)がintshortlonglong long、または__Did_you_really_just_dare_me_to_eat_my_left_shoe__であるため、必要はありません。


さらに、ドキュメントの形式として機能し、特定の変数が何であるかを一目で確認できます。以下を考慮してください。

int a, b;

....

if (a > b) {
    // Nothing wrong here, right?  They're both ints.
}

それでは、もう一度試してみましょう。

size_t a;
pid_t b;

...

if (a > b) {
    // Why are we comparing sizes to PIDs?  We probably messed up somewhere.
}

このように使用すると、何か問題が発生する前に潜在的に問題のあるコードのセグメントを見つけることができ、トラブルシューティングを他の方法よりもはるかに簡単にすることができます。

7
Justin Time

指摘すべきことの1つは、ほとんどの回答で、「pid_tを使用するとコードが異なるシステムで動作する」の線に沿って何かを見たことです。本当。

正確な表現は次のようにすべきだと思います:異なるシステムでコードを「コンパイル」します

たとえば、32ビットpid_tを使用するシステムでコードをコンパイルすると、おそらくを使用する別のシステムで実行すると壊れるバイナリが生成されます64ビットpid_t。

0
0xcurb