g++ 不会在模板代码中发出 -Wsign-compare

g++ doesn't issue -Wsign-compare in template code

我最近注意到,当有问题的代码在函数模板中时,g++ 不会发出 signed/unsigned 比较警告。这是一个示例:

// 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 转换为非常大的无符号值。但是编译应该对这个比较发出警告,No?

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

使用的 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.

Does anybody know why the template version of comparison doesn't throw warning?

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

The assertion failure is expected as the integer promotion

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