-gsign-compare警告用g ++表示

ale*_*ion 9 c++ g++ c++11

我有一个使用64位整数比较的代码.它看起来类似于以下内容:

#include <cstdio>

long long getResult()
{
    return 123456LL;
}

int main()
{
    long long result = getResult();

    if (result > 0x000FFFFFFFFFFFFFLL
        || result < 0xFFF0000000000000LL)
    {
        printf("Something is wrong.\n");

        if (result > 0x000FFFFFFFFFFFFFLL
            || result < -4503599627370496LL)
        {
            printf("Additional check failed too.\n");
        }
        else
        {
            printf("Additional check went fine.\n");
        }
    }
    else
    {
        printf("Everything is fine.\n");
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当这个代码用g ++编译(在Ubuntu 12.04 x64上尝试不同的版本:4.6.3,4.6.4,4.7.3,4.8.0)时带有标志-Wall -pedantic -std = c ++ 0x test.cpp -o测试我得到第一个if语句的第二行的-Wsign-compare警告(从g ++ - 4.8输出):

test.cpp:13:17: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
 || result < 0xFFF0000000000000LL)
             ^
Run Code Online (Sandbox Code Playgroud)

当测试程序运行时,我得到两行文本:

Something is wrong.
Additional check went fine.
Run Code Online (Sandbox Code Playgroud)

使用带有x86或x64架构的默认项目选项的MS Visual Studio 11 Express Update 2在Windows上编译相同代码时,我既没有得到警告也没有得到此输出,而是输出为:

Everything is fine.
Run Code Online (Sandbox Code Playgroud)

这是代码中的问题吗?如果是的话,你能指出它吗?或者是使用编译器的问题?

在第一个if语句中为第二个常量添加其他类型转换会删除g ++中的警告.

Jon*_*ely 11

根据标准中的[lex.icon],十六进制文字0xFFF0000000000000LL具有类型unsigned long long,因为该值不适合a long long(有关更多信息,请参阅C中的无符号十六进制常量十六进制长整数字"L"的C解释)这个.)

这意味着的G ++的警告是正确的,你是比较long long resultunsigned long long文字.

显然,作为无符号值,123456LL小于0xFFF0000000000000LL,所以G ++的结果也是正确的.

MSVC似乎有一个错误[编辑:或出于兼容性原因而行为不同,请参阅注释],因为此断言失败:

static_assert(0xFFF0000000000000LL > 0, "big number is big");
Run Code Online (Sandbox Code Playgroud)

MSVC给出了0xFFF0000000000000LLlong long 的文字类型,如MSVC接受的无效代码所示:

auto i = 0xFFF0000000000000LL;
long long& l = i;
Run Code Online (Sandbox Code Playgroud)

应该编译没有错误的C++ 03示例是:

template<typename T>
void f(T t)
{
    unsigned long long& l = t;
}

int main()
{
    f(0xFFF0000000000000LL);
}
Run Code Online (Sandbox Code Playgroud)

GCC,Clang,Intel和Solaris CC都是正确的,VC++错了.