为什么64位GCC警告在分配数组时将const int转换为long unsigned int?

Ose*_*Ose 8 c++ arrays 64-bit gcc

我有一个文件test.cpp,如下所示:

void f(const int n) {
  unsigned char *a=new unsigned char[n];
  delete[] a;
}

int main() {
  f(4);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用该-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]
Run Code Online (Sandbox Code Playgroud)

(第2行new是调用的行).对我来说,GCC应该给出关于分配数组的警告似乎很奇怪,但以下事情甚至更奇怪:

  1. 更换违规行unsigned char *a=new unsigned char[(long unsigned int)n];并没有消除警告,也没有使用static_cast<long unsigned int>().
  2. 如果产生任何警告f与签名定义void f(T n),这里T

    1. 任何大小的任何非常量,有符号或无符号整数类型,或
    2. 带符号的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
Run Code Online (Sandbox Code Playgroud)

7H3*_*3ju 0

const int 是一个有符号值,您正在将有符号值转换为无符号值。因此编译器会生成警告,表明在某些情况下,此转换可能会导致错误的计算。

  • `int` 也是有符号类型。但是,正如 OP 所说,如果参数声明为“int”类型,则不会出现警告。似乎是“const”专门触发了它。这是问题的关键点。 (3认同)