1

現在取り組んでいるコードでこれを見つけ、それが私が抱えているいくつかの問題の原因であると考えました。

どこかのヘッダーで:

enum SpecificIndexes{
    //snip
    INVALID_INDEX = -1
};

その後 - 初期化:

nextIndex = INVALID_INDEX;

そして使う

if(nextIndex != INVALID_INDEX)
{
    //do stuff
}

コードをデバッグすると、nextIndex の値が意味をなさない (非常に大きい) ため、次のように宣言されていることがわかりました。

unsigned int nextIndex;

そのため、INVALID_INDEX への初期設定は、unsigned int をアンダーフローして膨大な数に設定していました。それが問題の原因だと思いましたが、詳しく見ると、テスト

if(nextIndex != INVALID_INDEX)

つまり、nextIndex が「大きな +ve 値」の場合、if の本体を実行しませんでした。

これは正しいです?これはどのように起こっていますか?enum 値は変数と同じ型の unsigned int に暗黙的にキャストされているため、同じようにラップされていますか?

4

5 に答える 5

12

はい、すべてに。これは有効なコードであり、一般的に使用されるライブラリ側の C++ コードでもあり、最近の C++ ではさらにそうです (初めて見たときは奇妙ですが、実際には非常に一般的なパターンです)。

次に、列挙型は符号付き int ですが、符号なし int に暗黙的にキャストされます。これは、コンパイラによっては警告が表示される場合がありますが、依然として非常に一般的に使用されていますが、メンテナーに明確にするために明示的にキャストする必要があります。

于 2008-11-19T11:35:53.723 に答える
2

列挙型は、負の値が含まれているかどうか、およびコンパイラがどのように感じるかに応じて、符号付きまたは符号なしの整数型で表すことができます。この例には負の値が含まれているため、符号付き整数型で表す必要があります。

符号付き型と符号なし型の等価比較は安全であり、通常は作成者が意図したとおりに実行されます。符号付きの値は最初に符号なしに変換され、その結果は C++ 標準で定義されており、直感的です (少なくとも、一度整数が 2 の補数ではない場合を除いて、それほど直感的ではないかもしれませんが、通常は問題が発生することはありません)。

順序を比較すると、エラーが発生する可能性が高くなります。例えば:

SpecificIndexes value = INVALID_VALUE;
return (value >= 0);

false を返しますが:

unsigned int value = INVALID_VALUE;
return (value >= 0);

true を返します。特に「値」のタイプが使用時にそれほど明白でない場合、作成者は違いを理解しないことがあります。ただし、(value >= 0) はトートロジーであるため、コンパイラは 2 番目の例について警告する可能性があります。

于 2008-11-21T13:06:10.390 に答える
1

実際、-1 は、nextValue に割り当てられると、それに相当する符号なし値に暗黙的にキャストされます。同等の unsigned は、同じビット単位の表現を持つ値です (111111111111...、これは最大の unsigned 値です)。

その後、比較ステートメントで、別の暗黙のキャストが発生します。

したがって、これは現在は機能しますが、将来的に問題が発生する可能性があります。符号付きと符号なしの値を混在させることは決して良い考えではありません。

于 2008-11-19T11:35:03.833 に答える
0

C++ 標準では、実装で列挙型に符号付き型を使用できますが、必須ではありません。したがって、一般に、負の数を列挙型に入れることが安全であると想定することはできません。

于 2012-02-28T01:41:58.520 に答える
0

はい、列挙型は署名されていると思います。変化する

unsigned int nextIndex;

int nextIndex;

あなたのプログラムは動作するはずです。

于 2008-11-19T11:47:01.873 に答える