web-dev-qa-db-ja.com

C-整数が割り当てられているかどうかを確認する

整数が割り当てられていないかどうかを確認するにはどうすればよいですか?

int i; /* no assignment */

if (/* conditional statement here to check if int i is unassigned or not */) {
   printf("Integer is unassigned!\n");
} else {
   printf("Integer is assigned!\n");
}
28
Timothy

できません。 「未定義」のコンテンツが含まれます。つまり、その時点でそのメモリ位置に発生したことが含まれます。

。 。 。 iがグローバルスコープで宣言されていない限り、ゼロに初期化されます。

22
Binary Worrier

Cはこれを本質的にサポートしていません-配列の境界チェックを本質的にサポートしていないのと同じです。これは、速度/効率と安全性のトレードオフです。

一般に...変数を初期化します。

8
Amber

とても簡単です。初期化していないため、割り当てられていないことがわかります。

6
anon

iがグローバルまたは静的の場合、その値は0、それ以外の場合、その値は何でもかまいません。それがゴミかどうかを確認する方法はありません。

4
qrdl

初期化されていない値を使用すると、コンパイラの警告を要求できる場合があります。ただし、それらは完全に信頼できるわけではありません。DFAが期待したほど賢くない場合は、ときどき誤検出が発生し、たまに誤検出が発生することもあります(望みはありませんが、何も約束しません)。

GCCの場合:

-Wuninitialized -O1

条件付きコードを記述したい場合:

int a = 3;
int b;
int *p = (Rand() > Rand_MAX/2) ? &a : &b;
if (is_uninitialized(*p)) // blah

その後、あなたは運が悪いです。一部の動的言語とは異なり、Cには「未定義の値」という概念がありません。変数が初期化されていない場合、後でテストできる特別な値は与えられません。値はまったく指定されていないため、変数を使用した場合の動作は定義されていません。

4
Steve Jessop

他の人が指摘したように、独自の変数の1つが初期化されていないかどうかを検出するCプログラムを作成することはできません。変数が常に初期化されるように努める必要があります。

  • すべての変数が確実に初期化されるようにすることが目標である場合、 valgrind のようなツールは、初期化されていない変数の使用を動的に検出できます、高価なランタイム分析。

  • プライベートデータが確実に1回だけ初期化されるようにすることが目標である場合、通常の方法は、

    int i;
    static bool initialized = 0;
    
    ... 
    if (!initialized) {
      initialized = 1;
      i = ... i's initial value ...;
    }
    
4
Norman Ramsey

通常、変数はCライブラリによって0に設定されますが、必ずしもそうとは限りません。

しかし、基本的にはできません。たとえば、定義にデフォルト値を割り当てます。

int i = 0; /* Or what ever value you know won't be used elsewhere */

次に、コードを実行して、そこに値が設定されているかどうかを確認したい場合は、初期値と比較できます。

1
Makis

以前のすべての回答と同様に、実行時にそれを検出する方法はありません。ただし、ほとんどすべての 静的コード分析ツール は、割り当てられていない変数について警告します。

1
KIV

初期化(または割り当て)の前に変数を使用すると、エラーの重大な原因になります。実行時に確実にチェックすることはできませんが、コンパイル中またはコンパイル前に検出できます。

私はnotをコード内でチェックすることをお勧めします。これはコンパイラの警告を引き起こす可能性が高いため(値が割り当てられる前に変数「i」が使用されます)、新しいエラーが発生し、中規模から大規模のプログラムで成功する可能性はほとんどありません。

最良の方法は、静的コード分析ツール(QA/CやPCLintなど)を使用することです。高い警告感度レベルでコンパイラを使用することは無料のオプションであり、専用ツールとしての適用範囲ははるかに少なくなります。

コードレビューを実行する場合は、初期化されていない変数のチェックをチェックリストに含めることもできます。これは保証ではありませんが、レビュー担当者による手動チェックをトリガーします。

必要なランタイムチェックの場合は、変数を範囲外の値に初期化することから始めます。たとえば、そうでなければ正の値の場合は-1。次に、次を確認できます

#define UNASSIGNED_VALUE -1
    static int number_of_apples = UNASSIGNED_VALUE;
    if (UNASSIGNED_VALUE == number_of_apples)
    {
       // error handling
    }

これは真の「初期化されていない」変数ではありませんが、少なくとも、有効な範囲のランタイム割り当てが行われたかどうかを検出できます。

1
Adriaan

Cでは、整数は作成時に未定義の値をとります。これは、その整数の最初の使用が5893872を含むレジスタ/メモリロケーション/デバイスからのものである場合、それはその整数の値であることを意味します。 (マイレージは、デバッグ/リリースのコンパイルによって異なります。)

これを処理する通常の方法は、無意味なデフォルトを使用することです。

int number_of_widgets = -1;

...またはその状態を示すフラグ:

int number_of_widgets;
int number_of_widgets_assigned = 0;

if (number_of_widgets_assigned)
  do something
else
  do something else
number_of_widgets_assigned = 1;

何かが割り当てられているかどうかを検出する他の方法はありません-ハードウェアのデバッグ機能を使いたくなければ、この会話がそうではないのではないかと思います。

0

C#では、次のようにします。

Nullable<int> i = null; /* null assignment */

if (i == null) {
   printf("Integer is unassigned!\n");
} else {
   printf("Integer is assigned!\n");
}

ただし、これがCに変換されるかどうかはわかりません。

0
Akaoni

使用している変数が実行時に初期化(割り当て)されているかどうかを確認することは、Cにとって悪名高いことです。その言語のサポートはなく、実行時に利用できる情報は、初期化されていない値を完全に検出するには不十分です。 Valgrind/Memcheckなどの動的分析ツールは、非常に長い時間(プロセスのアドレス空間でメモリのすべてのバイトを追跡し、すべてのストアを調べてバイトを初期化済みとしてマークするなど)を使用して、使用する値が初期化されているかどうかを判断します。まだ偽陽性の影響を受けやすい。

プログラムでこのようなエラーを最小限に抑えようとしている場合、lintなどの静的分析ツールは、初期化されていない変数を使用しているかどうかを通知するのに適度に役立ちます。実際、私はほとんどのコンパイラーがあなたがこれをしているときにあなたに伝えるために最善を尽くすと信じています(しかし、それらは確かに完璧ではありません)。

0
Falaina