我有一个文件 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
在这种情况下关心常量和大小,为什么类型转换不能解决问题?
注意 1:我想在另一个编译器下测试它,但 Comeau 站点已关闭,我无法访问任何其他编译器,所以我无法判断这是符合标准的行为,还是 GCC 错误。
注意 2:test.cpp 是我拥有的“真实”C++ 文件中问题的一个最小示例,其中我摆脱警告的最佳方法是用以下内容包围有问题的行:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsign-conversion"
// ...
#pragma GCC diagnostic pop