Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ -Wsign比较警告在g++;_C++_C++11_G++ - Fatal编程技术网

C++ -Wsign比较警告在g++;

C++ -Wsign比较警告在g++;,c++,c++11,g++,C++,C++11,G++,我有一个使用64位整数比较的代码。它看起来类似于以下内容: #include <cstdio> long long getResult() { return 123456LL; } int main() { long long result = getResult(); if (result > 0x000FFFFFFFFFFFFFLL || result < 0xFFF0000000000000LL) {

我有一个使用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;
}
在Windows上使用MS Visual Studio 11 Express Update 2和x86或x64体系结构的默认项目选项编译相同的代码时,我既没有收到警告,也没有收到此输出,相反,输出为:

Everything is fine.
这是代码中的问题吗?如果是,你能指出它吗?还是使用的编译器有问题


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

根据标准中的[lex.icon],十六进制文本
0xfff000000000000ll
具有类型
无符号long
,因为该值不适合
long
(有关详细信息,请参阅和。)

这意味着G++的警告是正确的,您正在将
long-long结果
无符号long-long
文本进行比较

显然,作为一个无符号值,
123456LL
小于
0xfff000000000000ll
,因此G++的结果也是正确的

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

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);
}
模板
空隙f(T)
{
无符号长&l=t;
}
int main()
{
f(0xFFF0000000000000LL);
}

GCC、Clang、Intel和Solaris CC都正确地理解了这个示例,VC++理解错误。

这是一个很好的第一个问题,包括完整的示例和所有相关信息。
0xfff000000000000000000
,作为一个正值,不适合long-long。但是,它确实适合无符号long-long,因此GCC使用这种类型。后缀
LL
可用于强制编译器选择较长的类型(
1LL
为long-long),但如果不选择较小的类型,则需要对该类型进行强制转换(
(long-long)0xFFF0000000000000
(严格来说,这是实现定义的)).+1对于使用
static\u assert
和自动类型推断来验证bug的好方法:)VC++支持
long
作为C++11功能还是作为C++03扩展<代码>长Cux/Cux>不是C++ 11之前的标准C++,是吗?在clang的<代码> -FMS扩展< /COD>标志>代码> 0xFFF000 0 000 000 000 LL 已签名。我相信这是因为,正如@hvd所指出的,VC++在C++11之前有
long
,这种行为是兼容性所必需的。@hvd,问题被标记(只是后来添加的),VC++默认为C++11,不是吗?所有其他编译器也支持
long
(和
unsignedlong
!)几年前,C++11规则直接来自C99。我不知道Clang用那个标志改变了行为,所以这显然是VC++的已知/预期行为,而不仅仅是bug@JonathanWakely我问的不是这个问题,而是实施的问题。我怀疑VC++使用了C++03的一致性扩展,而不是C++11特性的错误实现。如果你说VC++默认为C++11(我真的不知道),而不是C++03加扩展,这就回答了我的问题,谢谢。
auto i = 0xFFF0000000000000LL;
long long& l = i;
template<typename T>
void f(T t)
{
    unsigned long long& l = t;
}

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