3

私たちはVS 2008を使用しています

多くの開発者が入力する大きな列挙型があります

この列挙型には __int64 型 (Microsoft 拡張機能) があり、列挙型の値が一意でないことをコンパイラに訴えさせたいと考えています。

それが通常の列挙型である場合、私は次のようにします:

enum E1
{
    E11 = 0x01F00,
    E12 = 0x01F00,
    E13
};
#pragma warning(push)
#pragma warning(error: 4061)
#pragma warning(error: 4062)
void F(E1 e1)
{
    switch (e1)
    {
    case E11:
    case E12:
    case E13:
        return;
    }
}
#pragma warning(pop)

E1に2つの同じ値がある場合、関数Fはエラーになります

開発者がスイッチに新しい値を追加するのを忘れた場合、別のエラーが発生します

しかし、私の列挙型は __int64 (または long long) です

そして、E1 e1に対して同じスイッチを実行しようとすると、値が切り捨てられ、値に不満があり、違いは0x100000000または0x200000000のいずれかです....

e1 を __int64 にキャストすると、開発者がスイッチに新しい値を追加するのを忘れても、コンパイラは文句を言いません (そのため、チェック関数全体が役に立たなくなります)。

質問: 誰かが私に何ができるか知っていますか? または、VS 2008 (または C++) には、enum : __int64 が一意の値しかないことを確認するための別の手段がありますか?

4

2 に答える 2

2

あなたのコメントから、列挙型自体に集約 (結合) フラグがないと仮定します。その場合、2 つの列挙型を使用して、間違いを犯しにくくすることができます。それでもコンパイラを破壊することはできますが、ここでの本当の問題ではないと思います。

enum Bit_Index
{
    FLAG1_INDEX,
    FLAG2_INDEX,
    FLAG_FANCY_INDEX,
    LAST_INDEX
};

#define DECLARE_BIT_VALUE(att) att##_VALUE = 1ULL << att##_INDEX
enum Bit_Value
{
    DECLARE_BIT_VALUE(FLAG1),
    DECLARE_BIT_VALUE(FLAG2),
    DECLARE_BIT_VALUE(FLAG_FANCY),

    // Declared NOT using the macro so we can static assert that we didn't forget
    // to add new values to this enum.
    LAST_BIT   // Mainly a placeholder to prevent constantly having to add new commas with new ids.
};
#undef DECLARE_BIT_VALUE

次に、実装ファイルで static_assert して、列挙型がずれないようにします。

// Make sure to the best of our abilities that we didn't mismatch the index/bit enums.
BOOST_STATIC_ASSERT((LAST_BIT - 1) == (1U << (LAST_INDEX - 1)));
于 2012-06-29T14:47:59.740 に答える
0

誰かが私がそれについて何ができるか知っていますか.

他の答えは、アルゴリズム分析です。静的分析は、必ずしもセキュリティの脆弱性の検索ではありません。残念ながら、この場合、制約を検証するために外部ツールを使用する必要があります。私はそれを実行するのを手伝うことができます。

于 2012-06-29T22:32:35.483 に答える