getpid()
typeの値を返すpid_t
の代わりにunsigned int
?またはint
?これはどのように役立ちますか?
これは移植性に関係していると思いますか? pid_t
は、異なるサイズのint
sなどを持つ異なるプラットフォーム間で同じサイズですか?
それは逆だと思います:たとえば、PIDが16ビットか32ビット(またはそれ以上)かどうかに関係なく、プラットフォーム間でプログラムを移植可能にします。
その理由は、厄介な歴史的な実装がまだ適合していることを許可するためです。あなたの歴史的な実装が(むしろ一般的)を持っていたと仮定します:
short getpid(void);
もちろん、最新のシステムはpidが少なくとも32ビットであることを望んでいますが、標準が義務付けられている場合:
int getpid(void);
short
を使用していたすべての歴史的な実装は不適合になります。これは受け入れられないと見なされたので、pid_t
が作成され、実装はpid_t
を任意の方法で定義できました。
Pidを格納するのに十分な大きさの型を使用する限り、独自のコードでpid_t
を使用する義務はないことに注意してください(たとえば、intmax_t
はうまく機能します)。 pid_t
必要が存在する唯一の理由は、標準がgetpid
、waitpid
などを定義することです。
異なるプラットフォームおよびオペレーティングシステムでは、異なるタイプ(pid_tなど)は、32ビットマシンでは32ビット(unsigned int)、64ビットマシンでは64ビット(unsigned long)になります。または、他の何らかの理由で、オペレーティングシステムが異なるサイズを選択する場合があります。さらに、この変数が任意の数字ではなく「オブジェクト」を表すことをコードを読み取るときに明確にします。
その目的は、pid_t
またはその他の種類のプラットフォームをプラットフォームに依存せずに、実際の実装方法に関係なく適切に動作するようにすることです。この方法は、次のようなプラットフォームに依存しないタイプに使用されます。
pid_t
:コーディング対象のシステムにPIDを格納するのに十分な大きさが必要です。私が知っている限り、int
にマップしますが、私はGNU Cライブラリに精通していません。size_t
:unsigned
演算子の結果を格納できるsizeof
変数。通常、サイズはコーディング対象のシステムのWordサイズと同じです。int16_t
(intX_t
):プラットフォームに関係なく、正確に16ビットである必要があり、2を使用しないプラットフォームでは定義されませんn-ビットバイト(通常8または16ビット)、またははるかに少ない頻度で、より大きなタイプのうち正確に16ビットにアクセスする手段を提供します(たとえば、PDP-10の「バイト」は任意の数の連続したビットです) 36ビットのWordであるため、正確に16ビットである可能性があります)、したがって、16ビットの2の補数整数型(36ビットシステムなど)をサポートしません。一般的に、最新のコンピューターではshort
にマップされますが、古いコンピューターではint
になります。int_least32_t
(int_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)がint
、short
、long
、long 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.
}
このように使用すると、何か問題が発生する前に潜在的に問題のあるコードのセグメントを見つけることができ、トラブルシューティングを他の方法よりもはるかに簡単にすることができます。
指摘すべきことの1つは、ほとんどの回答で、「pid_tを使用するとコードが異なるシステムで動作する」の線に沿って何かを見たことです。本当。
正確な表現は次のようにすべきだと思います:異なるシステムでコードを「コンパイル」します。
たとえば、32ビットpid_tを使用するシステムでコードをコンパイルすると、おそらくを使用する別のシステムで実行すると壊れるバイナリが生成されます64ビットpid_t。