I recently noticed that g++ doesn't issue signed/unsigned comparison warning when the offending code is in a function template. Here is a sample:
// 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;
}
And I'm compiling and executing it like this:
$ 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)
The assertion failure is expected as the integer promotion will convert -5 to really large unsigned value. But the compilation should have issued warning about this comparison, No?
I might be missing something basic here but I searched online and couldn't find anything relevant. Does anybody know why the template version of comparison doesn't throw warning?
GCC version used:
$ 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.
It is probably a bug (quality of implementation issue) in that version of GCC. GCC 5.5.0 for example does not fail to issue a diagnostic for the example program, so the issue seems to have been fixed in later versions.
To be pedantic, this conversion is not classified as integer promotion.