简体   繁体   English

C4127:条件表达式是常量

[英]C4127: Conditional Expression is Constant

The following code generates warning C4127 (conditional expression is constant) in Visual Studio 2010 (where alias_wchar_t is an alias for wchar_t): 以下代码在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
}

What's the most elegant way to resolve this, short of suppressing the warning? 除了抑制警告之外,解决这个问题的最优雅方法是什么?

The best solution I've come up with is to stuff the conditional into a static bool, and use that as the condition. 我想出的最好的解决方案是将条件填充到静态bool中,并将其用作条件。 There's a goodly amount of code above and below the if-else, so I wrap the whole thing in braces to limit the scope of the variable as much as possible: 在if-else之上和之下都有大量的代码,所以我将整个东西包装在大括号中以尽可能地限制变量的范围:

// <snip>

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

// <snip>

This feels pretty gross though. 这感觉非常糟糕。 This seems like it should be resolvable at compile-time rather than runtime, but the preprocessor doesn't know about sizeof. 这似乎应该在编译时而不是运行时可解析,但预处理器不知道sizeof。 Is there a cleaner, more elegant way to resolve this? 是否有更清洁,更优雅的方法来解决这个问题?

It looks like you know what is going on, and you are fine with this. 看起来你知道发生了什么,你对此很好。

Compiler pragma s are meant for cases like that: 编译器编译pragma适用于以下情况:

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

Essentially, you are telling the compiler (and even more importantly, to human readers of your code) that you have reviewed the warning, and that you know what you are doing. 从本质上讲,您告诉编译器(更重要的是,您的代码的人类读者)您已经查看了警告,并且您知道自己在做什么。

What's the most elegant way to resolve this, short of suppressing the warning? 除了抑制警告之外,解决这个问题的最优雅方法是什么?

The condition is known at compile time, so you can make the check at compile time, too. 这个条件在编译时是已知的,所以你也可以在编译时进行检查。 Don't use an if , just let the compiler insert a call to the right function. 不要使用if ,只需让编译器插入对正确函数的调用。 Here is a complete example: 这是一个完整的例子:

#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();
}

Whether that's really more elegant than your original code (with just that particular compiler warning turned off for this compilation unit) is opinion-based, I'd say. 我是否会说,这是否比原始代码更优雅(只有关闭此编译单元的特定编译器警告)是基于意见的。

In any case, this compiles with no warnings at /W4 with VC 2013. 在任何情况下,使用VC 2013在/W4编译时都没有警告

An other way to disable the warning is to create a dummy identity function and use it on one of the constants. 禁用警告的另一种方法是创建一个虚拟身份函数并在其中一个常量上使用它。

// Define this somewhere
template<typename T> const T& identity(const T& t) { return t; }

...

// NB: 'identity' used only to remove "warning C4127"
if (identity(sizeof(alias_wchar_t)) == sizeof(wchar_t))
{
    // do stuff
}
else
{
    // do other stuff
}

This is not perfect but seems more lightweight than other solutions and reusable for different type of constants. 这并不完美,但似乎比其他解决方案更轻量级,并且可以重复使用不同类型的常量。

This is what I have come up with. 这就是我想出的。 It does not cause any warnings in Microsoft Visual Studio 2013 and it does not require that you use Visual C++ specific Pragmas. 它不会在Microsoft Visual Studio 2013中引起任何警告,也不要求您使用Visual C ++特定的Pragma。

First define the following template class. 首先定义以下模板类。

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

Then use it as follows. 然后按如下方式使用它。

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

I got the idea from the C++14 std::conditional described at http://en.cppreference.com/w/cpp/types/conditional . 我从http://en.cppreference.com/w/cpp/types/conditional中描述的C ++ 14 std :: conditional中得到了这个想法。

In C++17, the solution is to use if constexpr: 在C ++ 17中,解决方案是使用constexpr:

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

Reference: Visual C++ Blog 参考: Visual C ++博客

If it's just a constant expression then use: 如果它只是一个常量表达式,那么使用:

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
}

It appears the c4127 is generated by the mere action of evaluating a constant expression in the control statement. 看起来c4127是仅仅通过在控制语句中评估常量表达式而生成的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM