整数が割り当てられていないかどうかを確認するにはどうすればよいですか?
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");
}
整数が割り当てられていないかどうかを確認するにはどうすればよいですか?
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");
}
できません。「未定義」のコンテンツが含まれます。つまり、その時点でそのメモリ位置にあるものが含まれます。
. . . i がグローバル スコープで宣言されていない限り、ゼロに初期化されます。
C は本質的にこれをサポートしていません - 配列の境界チェックを本質的にサポートしていないのと同じです。これは、速度/効率と安全性のトレードオフです。
一般的に...変数を初期化します。
i
がグローバルまたは静的である場合、その値は になります0
。それ以外の場合、その値は何でもかまいません。ガベージかどうかを調べる方法はありません。
他の人が指摘したように、独自の変数の 1 つが初期化されていないかどうかを検出する C プログラムを作成することはできず、変数が常に初期化されるように努力する必要があります。
すべての変数が確実に初期化されるようにすることが目標の場合、valgrindのようなツールは、高価なランタイム分析を通じて、初期化されていない変数の使用を動的に検出できます。
プライベート データが 1 回だけ初期化されるようにすることが目標である場合、通常の方法は、次の方法で保護することです。
int i;
static bool initialized = 0;
...
if (!initialized) {
initialized = 1;
i = ... i's initial value ...;
}
とても簡単です。初期化していないため、割り当てられていないことがわかります。
初期化されていない値を使用すると、コンパイラの警告を要求できる場合があります。ただし、それらは完全に信頼できるわけではありません。DFA が期待したほど賢くない場合に、時折偽陽性が発生したり、場合によっては偽陰性が発生したりすることがあります (そうでないことを望みますが、約束はしません)。
GCC の場合:
-Wuninitialized -O1
条件付きコードを書きたい場合:
int a = 3;
int b;
int *p = (rand() > RAND_MAX/2) ? &a : &b;
if (is_uninitialized(*p)) // blah
その後、あなたは運が悪いです。一部の動的言語とは異なり、C には「未定義の値」という概念がありません。変数が初期化されていない場合、後でテストできる特別な値が与えられません。値がまったく与えられていないため、変数を使用したときに何が起こるかは未定義です。
通常、変数は C ライブラリによって 0 に設定されますが、必ずしもそうとは限りません。
でも、基本的にはできません。定義でデフォルト値を割り当てます。たとえば、次のようになります。
int i = 0; /* Or what ever value you know won't be used elsewhere */
次に、コードを実行して値がそこに設定されているかどうかを確認したい場合は、初期値と比較できます。
以前のすべての回答と同様に、実行時にそれを検出する方法はありません。ただし、ほとんどすべての静的コード分析ツールは、割り当てられていない変数について警告します。
初期化 (または割り当て) の前に変数を使用すると、重大なエラーの原因になります。実行時に確実にチェックすることはできませんが、コンパイル中またはコンパイル前に検出できます。
コード内でチェックしないことをお勧めします。これにより、コンパイラの警告が発生する可能性があるため (値が割り当てられる前に変数 'i' が使用される)、新しいエラーが発生し、中規模から大規模のプログラムで成功する可能性はほとんどありません。
最善の方法は、静的コード分析ツール (QA/C や PCLint など) を使用することです。高い警告感度レベルでコンパイラを使用することは無料のオプションであり、専用ツールとしての適用範囲ははるかに少なくなります。
コード レビューを実行する場合は、初期化されていない変数のチェックをチェックリストに含めることもできます。これは保証されませんが、レビュー担当者による手動チェックがトリガーされます。
実行時チェックが必要な場合は、変数を範囲外の値に初期化することから始めることができます。たとえば、それ以外の正の値の場合は -1 です。次に、次のことを確認できます
#define UNASSIGNED_VALUE -1
static int number_of_apples = UNASSIGNED_VALUE;
if (UNASSIGNED_VALUE == number_of_apples)
{
// error handling
}
これは真の「初期化されていない」変数ではありませんが、少なくとも、有効な範囲で実行時の割り当てが行われたかどうかを検出できます。
使用している変数が実行時に初期化(割り当て)されているかどうかを確認することは、Cにとって悪名高いほど困難です。言語サポートがなく、実行時に利用可能な情報は、初期化されていない値を完全に検出するには不十分です。Valgrind / Memcheckなどの動的分析ツールは非常に長い時間をかけて(プロセスのアドレス空間内のメモリのすべてのバイトを追跡し、すべてのストアを調べてバイトを初期化済みとしてマークするなど)、使用する値が初期化されているかどうかを判断します。まだ誤検知の影響を受けやすいです。
プログラムでこのようなエラーを最小限に抑えようとしている場合は、lintなどの静的分析ツールを使用すると、初期化されていない変数を使用しているかどうかを通知できます。実際、ほとんどのコンパイラーは、これを実行しているときに最善を尽くして通知すると思います(ただし、完全ではありません)。
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;
何かが割り当てられているかどうかを検出する方法は他にありません。ただし、ハードウェアのデバッグ機能を使いたい場合や、それがこの会話の目的ではないと思われる場合を除きます。
C# では、次のように使用します。
Nullable<int> i = null; /* null assignment */
if (i == null) {
printf("Integer is unassigned!\n");
} else {
printf("Integer is assigned!\n");
}
ただし、これが C に変換されるかどうかはわかりません。