I have a file test.cpp that looks like this:
void f(const int n) {
unsigned char *a=new unsigned char[n];
delete[] a;
}
int main() {
f(4);
return 0;
}
Compiling it in 64-bit GCC with the -Wsign-conversion
flag produces the warning:
test.cpp:2:39: warning: conversion to ‘long unsigned int’ from ‘const int’ may change the sign of the result [-Wsign-conversion]
(line 2 is the line in which new
is called). It seems strange to me that GCC should give this warning about allocating an array, but the following things are even stranger:
- Replacing the offending line with
unsigned char *a=new unsigned char[(long unsigned int)n];
does not get rid of the warning, nor does usingstatic_cast<long unsigned int>()
. No warning is produced if
f
is defined with the signaturevoid f(T n)
, whereT
is- any non-const, signed or unsigned integer type of any size, or
- a signed 64-bit integer type.
It does however produce warnings when
T
is any const signed integer type smaller than 64-bits.
Bearing in mind that I'm on a 64-bit (Linux) machine, why does the sign-conversion warning care about the constness and size of n
in this case, and why doesn't type casting fix the problem?
Note 1: I wanted to test this under another compiler, but the Comeau site is down, and I don't have access to any other compilers, so I can't tell if this is standard-compliant behaviour, or a GCC bug.
Note 2: test.cpp is a minimal example of a problem from a "real" C++ file that I have in which the best way for me to get rid of the warning was to surround the offending line with:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsign-conversion"
// ...
#pragma GCC diagnostic pop