c++ - -g++ 中的 Wsign-compare 警告

标签 c++ c++11 g++

我有一个使用 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;
}

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

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

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

Something is wrong.
Additional check went fine.

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

Everything is fine.

是不是代码有问题?如果是的话,你能指点一下吗?还是使用的编译器有问题?

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

最佳答案

根据标准中的 [lex.icon],十六进制文字 0xFFF0000000000000LL 的类型为 unsigned long long,因为该值不适合 long long(有关这方面的更多信息,请参阅 Unsigned hexadecimal constant in C?C interpretation of hexadecimal long integer literal "L"。)

这意味着 G++ 的警告是正确的,您正在将 long long resultunsigned long long 文字进行比较。

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

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

static_assert(0xFFF0000000000000LL > 0, "big number is big");

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

auto i = 0xFFF0000000000000LL;
long long& l = i;

一个 C++03 的编译应该没有错误的例子是:

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

int main()
{
    f(0xFFF0000000000000LL);
}

GCC、Clang、Intel 和 Solaris CC 都正确地使用了这个示例,而 VC++ 却错误地使用了它。

关于c++ - -g++ 中的 Wsign-compare 警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16834588/

相关文章:

c++ - operator= in c++(11)工作方向

c++ - 获取模板模板类中可变类型的类型

c++ - 适用于 Linux 的 C++ 代理脚本

c++ - 可变递归模板

c++ - 为什么我必须将原始图像数据的宽度除以 3?

c++ - 在每个源文件中包含一个头文件

c++ - 拦截服务器和客户端中的 gRPC C++ 调用

c++ - GCC/G++ 编译器设置 GUI

c++ - g++ 编译顺序重要吗?

c++ - 如何使用 libsndfile C++ 包装器读取/写入音频文件?