【问题标题】:g++ doesn't issue -Wsign-compare in template codeg++ 不会在模板代码中发出 -Wsign-compare
【发布时间】:2019-09-15 23:05:20
【问题描述】:

我最近注意到,当违规代码位于函数模板中时,g++ 不会发出有符号/无符号比较警告。这是一个示例:

// signed_unsigned.cc
#include <cassert>
#include <string>

template<typename T, typename U>
bool compare(T t, U u) {
    return t >= u;
}

int main(int argc, char** argv)
{
    size_t x = strtoul(argv[1], 0, 0);
    int y = strtol(argv[2], 0, 0);
    // bool chk = (x >= y);   // if I use this statement instead, it throws [-Wsign-compare] warning
    bool chk = compare(x, y);
    assert(chk);
    return 0;
}

我正在像这样编译和执行它:

$ g++ -std=gnu++11 signed_unsigned.cc -Wall -Wsign-compare
$ ./a.out 0 -5
a.out: signed_unsigned.cc:15: int main(int, char**): Assertion `chk' failed.
Aborted (core dumped)

预计断言失败,因为整数提升会将 -5 转换为非常大的无符号值。但是编译应该对这个比较发出警告,不是吗?

我可能在这里遗漏了一些基本的东西,但我在网上搜索并找不到任何相关的东西。有谁知道为什么模板版本的比较不会引发警告?

使用的 GCC 版本:

$ g++ --version
g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

【问题讨论】:

    标签: c++ g++ gcc-warning g++4.8


    【解决方案1】:

    有人知道为什么模板版本的比较不会引发警告吗?

    这可能是那个版本的 GCC 中的一个错误(实施质量问题)。例如,GCC 5.5.0 不会为示例程序发出诊断失败,因此该问题似乎已在以后的版本中得到修复。

    断言失败预期为整数提升

    为了迂腐,这种转换不属于整数提升。

    【讨论】:

    • 按我的理解,为什么说这不是整数提升?由于无符号具有更高的等级,编译器不会将有符号整数提升为无符号整数吗?
    • @anni 否。有符号整数转换为无符号类型。此算术转换在操作数提升后执行。在这种情况下不会发生提升,因为两个操作数的大小都是 int 或更大。
    • 通过安装 gcc5.5 并运行测试确认了答案。谢谢!希望这可以帮助一些像我一样困惑的灵魂将来......
    猜你喜欢
    • 2013-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-14
    • 2011-01-10
    • 2020-07-30
    • 2012-05-22
    • 2015-06-29
    相关资源
    最近更新 更多