型の最大値をポータブルに決定するにはどうすればよいpid_t
ですか? 私のシステムには PID_MAX 定数がありません。
(注:システムがプロセスに割り当てる事実上の最大値ではなく、データ型によって許可される最大値を意味します。)
ユースケース:ユーザーが指定した pid の文字列仕様を に変換してpid_t
おり、ユーザーの入力が型の容量を超えないようにしたいと考えています。
過去に私が時々行ったことは、より大きなデータ型を使用し、小さな型に変換するとすぐに大きな型に戻して、値が変更されていないことを確認することでした。
たとえば、代わりに int64_t を使用したとします。次のようになります。
int64_t my_pid64;
/* ... parse string value into my_pid64 ... */
pid_t my_pid = (pid_t) my_pid64;
if ((int64_t) my_pid != my_pid64) /* check that value was not out of range of pid_t */
{
/* ... handle error ... */
}
より大きなデータ型を使用するための優れたオプションはありません。「long」は最大のプリミティブ整数データ型でしたが、一部の一般的なコンパイラ/アーキテクチャではもはや当てはまりません。Linux であっても (以下のコメントを参照)。一方、intmax_t 型はライブラリ サポートが不十分です。その結果、実際には int64_t の方が役立つ場合があります。
ただし、基本的に、より大きなデータ型のオプションはおそらく long 、int64_t および intmax_t です。
POSIX (2008) は次のように述べています。
blksize_t、pid_t、および ssize_t は符号付き整数型でなければなりません。
と:
実装は、blksize_t、pid_t、size_t、ssize_t、および suseconds_t の幅が long 型の幅を超えない 1 つまたは複数のプログラミング環境をサポートする必要があります。
したがって、ユーザー文字列を に変換しlong
、 を使用して pid_t 型のオーバーフローをチェックできますlong pid; .. pid == (pid_t)pid
。
スティーブンの答えは良いアプローチです。
しかし、未定義の動作に依存せずに最大値を決定したい場合はpid_t
、次の方法が最適だと思います。
#include <sys/types.h>
#include <limits.h>
#include <stdlib.h>
static inline pid_t get_max_pid_t()
{
if (sizeof(pid_t) == sizeof(short)) return SHRT_MAX;
if (sizeof(pid_t) == sizeof(int)) return INT_MAX;
if (sizeof(pid_t) == sizeof(long)) return LONG_MAX;
#if defined(LLONG_MAX) // C99
if (sizeof(pid_t) == sizeof(long long)) return LLONG_MAX;
#endif
abort();
}
pid_t
POSIXは、 が符号付き整数型であることを保証します。このコードは、符号付き整数型のサイズがその型を一意に決定すると想定しています。これは素晴らしい仮定だと思いますが、規格がそれを保証しているかどうかはわかりません。
適切なコンパイラーは、これらすべてをインライン化して定数伝搬し、存在しないようにするため、パフォーマンスは問題になりません。
(余談: C++ では、記述std::numeric_limits<pid_t>::max()
して完了します。)
ヘッダーの 1 つで:
#ifndef PID_MAX
#define PID_MAX INT_MAX // or whatever value you see fit
#endif
環境変数に基づくサーバー/OS 依存の定義に基づいて実行することもできます。
見てください: 同様の投稿: Linux での最大 PID