次のようなファイル test.cpp があります。
void f(const int n) {
unsigned char *a=new unsigned char[n];
delete[] a;
}
int main() {
f(4);
return 0;
}
-Wsign-conversion
フラグを指定して 64 ビット GCC でコンパイルすると、次の警告が表示されます。
test.cpp:2:39: warning: conversion to ‘long unsigned int’ from ‘const int’ may change the sign of the result [-Wsign-conversion]
(2 行目はnew
が呼び出される行です)。配列の割り当てについて GCC がこの警告を表示するのは奇妙に思えますが、次のことはさらに奇妙です。
- 問題のある行を に置き換えて
unsigned char *a=new unsigned char[(long unsigned int)n];
も、警告は取り除かれませんstatic_cast<long unsigned int>()
。 f
が署名void f(T n)
で定義されている場合、警告は生成されませんT
。- 任意のサイズの非定数、符号付きまたは符号なし整数型、または
- 符号付き 64 ビット整数型。
ただし
T
、const 符号付き整数型が 64 ビットより小さい場合は、警告が生成されます。
私は64ビット(Linux)マシンを使用していることを念頭に置いてn
、この場合、符号変換の警告がconstnessとサイズを気にするのはなぜですか?また、型キャストで問題が解決しないのはなぜですか?
注 1: 別のコンパイラでこれをテストしたかったのですが、Comeau サイトがダウンしており、他のコンパイラにアクセスできないため、これが標準準拠の動作なのか GCC のバグなのかわかりません。
注2:test.cppは、私が持っている「実際の」C++ファイルの問題の最小限の例であり、警告を取り除くための最良の方法は、問題のある行を次のように囲むことでした。
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsign-conversion"
// ...
#pragma GCC diagnostic pop