I have a code which uses comparison of 64-bit integers. It looks similar to the following:
#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;
}
When this code is compiled in g++ (tried different versions on Ubuntu 12.04 x64: 4.6.3, 4.6.4, 4.7.3, 4.8.0) with flags -Wall -pedantic -std=c++0x test.cpp -o test I get -Wsign-compare warning for second line of the first if statement (output from g++-4.8):
test.cpp:13:17: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
|| result < 0xFFF0000000000000LL)
^
And when the test program is run I get two lines of text:
Something is wrong.
Additional check went fine.
When compiling same code on Windows using MS Visual Studio 11 Express Update 2 with default project options for either x86 or x64 architecture I don't get neither the warning nor this output, instead the output is:
Everything is fine.
Is it a problem in the code? If yes, could you point it? Or is it a problem with the compiler used?
Adding additional type cast for the second constant in the first if statement removes the warning in g++.
To suppress this warning use the unused attribute (see Variable Attributes). This warning is also enabled by -Wunused , which is enabled by -Wall . Warn whenever a static function is declared but not defined or a non-inline static function is unused. This warning is enabled by -Wall .
You can make all warnings being treated as such using -Wno-error. You can make specific warnings being treated as such by using -Wno-error=<warning name> where <warning name> is the name of the warning you don't want treated as an error. If you want to entirely disable all warnings, use -w (not recommended).
Passing -fno-diagnostics-show-option will prevent Clang from printing the [-Wextra-tokens] information in the diagnostic. This information tells you the flag needed to enable or disable the diagnostic, either from the command line or through #pragma GCC diagnostic.
To answer your question about disabling specific warnings in GCC, you can enable specific warnings in GCC with -Wxxxx and disable them with -Wno-xxxx. From the GCC Warning Options: You can request many specific warnings with options beginning -W , for example -Wimplicit to request warnings on implicit declarations.
According to [lex.icon] in the standard, the hexadecimal-literal 0xFFF0000000000000LL
has type unsigned long long
, because the value doesn't fit in a long long
(see Unsigned hexadecimal constant in C? and C interpretation of hexadecimal long integer literal "L" for more information on this.)
This means G++'s warning is correct, you are comparing long long result
to an unsigned long long
literal.
Clearly as an unsigned value, 123456LL
is less than 0xFFF0000000000000LL
, so G++'s result is also correct.
MSVC seems to have a bug [Edit: or behaves differently for compatibility reasons, see comments], because this assertion fails:
static_assert(0xFFF0000000000000LL > 0, "big number is big");
MSVC gives the literal 0xFFF0000000000000LL
type long long, as shown by this invalid code that is accepted by MSVC:
auto i = 0xFFF0000000000000LL;
long long& l = i;
A C++03 example that should compile without errors is:
template<typename T>
void f(T t)
{
unsigned long long& l = t;
}
int main()
{
f(0xFFF0000000000000LL);
}
GCC, Clang, Intel and Solaris CC all get this example right, VC++ gets it wrong.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With