19

次のコードは、Visual Studio 2010 で警告 C4127 (条件式は定数) を生成します (ここで、alias_wchar_t は wchar_t のエイリアスです)。

if (sizeof(alias_wchar_t) == sizeof(wchar_t)) // warning occurs here
{
    // do stuff
}
else
{
    // do other stuff
}

警告を抑制する以外に、これを解決する最もエレガントな方法は何ですか?

私が思いついた最善の解決策は、条件を静的ブールに詰め込み、それを条件として使用することです。if-else の上下にかなりの量のコードがあるため、変数のスコープをできるだけ制限するために、全体を中かっこで囲みます。

// <snip>

{
    static bool isSameSize = (sizeof(alias_wchar_t) == sizeof(wchar_t));
    if (isSameSize)
    {
        // do stuff
    }
    else
    {
        // do other stuff
    }
}

// <snip>

しかし、これはかなりひどい気がします。これは、実行時ではなくコンパイル時に解決できるように思われますが、プリプロセッサは sizeof を認識していません。これを解決するためのよりクリーンでエレガントな方法はありますか?

4

6 に答える 6

8

C++17 では、解決策は if constexpr を使用することです。

if constexpr (sizeof(alias_wchar_t) == sizeof(wchar_t)) // warning occurs here
{
    // do stuff
}
else
{
    // do other stuff
}

参考:Visual C++ ブログ

于 2018-11-01T13:40:56.910 に答える
7

警告を抑制する以外に、これを解決する最もエレガントな方法は何ですか?

条件はコンパイル時にわかっているので、コンパイル時にチェックすることもできます。を使用しないでくださいif。コンパイラに適切な関数への呼び出しを挿入させてください。完全な例を次に示します。

#include <iostream>

typedef short alias_wchar_t; // for testing

template<bool Condition>
struct DoStuff
{
};

template<>
struct DoStuff<true>
{
    static void doStuff()
    {
        std::cout << "sizeof(alias_wchar_t) == sizeof(wchar_t)\n"; 
    }
};

template<>
struct DoStuff<false>
{
    static void doStuff()
    {
        std::cout << "sizeof(alias_wchar_t) != sizeof(wchar_t)\n"; 
    }
};

void doStuff()
{
    DoStuff<sizeof(alias_wchar_t) == sizeof(wchar_t)>::doStuff();
}

int main()
{
    doStuff();
}

それが元のコードよりも本当に洗練されているかどうか (このコンパイル単位で特定のコンパイラ警告をオフにした場合) は、意見に基づいていると思います。

いずれにせよ、これは VC 2013で警告なしでコンパイルされます。/W4

于 2014-08-29T20:10:02.887 に答える
7

何が起こっているのか知っているようで、これで問題ありません。

Compilerpragmaは、次のような場合を対象としています。

__pragma(warning(push))
__pragma(warning(disable:4127))
if (sizeof(alias_wchar_t) == sizeof(wchar_t)) {
__pragma(warning(pop))
}

基本的に、警告を確認したこと、および何を行っているかを知っていることをコンパイラに伝えます (さらに重要なことには、コードを読む人間に伝えます)。

于 2014-08-29T18:24:32.610 に答える
3

これが私が思いついたものです。Microsoft Visual Studio 2013 では警告は発生せず、Visual C++ 固有のプラグマを使用する必要もありません。

まず、次のテンプレート クラスを定義します。

template <bool b>
struct condition
{
    static bool test()
    {
        return true;
    }
};
template <>
struct condition<false>
{
    static bool test()
    {
        return false;
    }
};

次に、次のように使用します。

if (condition<sizeof(alias_wchar_t) == sizeof(wchar_t)>::test())

http://en.cppreference.com/w/cpp/types/conditionalで説明されている C++14 std::conditional からアイデアを得ました。

于 2014-08-29T19:15:23.997 に答える
1

それが単なる定数式の場合は、次を使用します。

typedef wchar_t alias_wchar_t;
bool constExpression = sizeof(alias_wchar_t) == sizeof(wchar_t);
if (constExpression) // potential warning
{
    // do stuff
}
else
{
    // do other stuff
}

c4127 は、制御ステートメントで定数式を評価するという単なるアクションによって生成されたようです。

于 2016-03-22T05:08:32.847 に答える