【问题标题】:Initializing a two dimensional array with class static const integers使用类静态常量整数初始化二维数组
【发布时间】:2020-03-05 11:56:07
【问题描述】:

我将一个三维数组声明为类成员,使用静态 const 类成员作为前两个边界:

class A
{
    static const uint8_t screenWidth = 256;
    static const uint8_t screenHeight = 240;

    uint8_t buffer[screenHeight][screenWidth ][3];
}

在 Visual Studio 2019 中,我收到以下(奇怪的?)错误:

Error (active)  E0098   an array may not have elements of this type

如果我使用“枚举破解”来声明类本地编译时整数常量,它可以工作:

class A
{
    enum { SH = 240, SW = 256};
    uint8_t buffer[SH][SW][3];
}

前一个示例不应该是符合 C++11 的代码吗? (我猜是 Visual Studio 2019 编译器)。

【问题讨论】:

标签: c++ arrays initialization constants


【解决方案1】:

我认为uint8_t 类型的对象无法包含值 256。:)

为什么不直接使用 size_t 类型而不是 uint8_t 类型?

static const size_t screenWidth = 256;
static const size_t screenHeight = 240;

【讨论】:

  • @Luca 一般来说,这是一个坏主意。来自 C++ 标准“如果初始值设定项子句是一个表达式并且需要窄转换 (8.5.4) 来转换表达式,则程序格式错误”在您的情况下,该值被截断为 0。
【解决方案2】:

你遇到的问题是,在声明中:

static const uint8_t screenWidth = 256;

256uint8_t 类型无效(范围是 0 到 255),它会“翻转”以提供 实际 零值strong> - 对数组维度无效。

使您的维度“常量”更大的类型,您的代码将起作用:

class A {
    static const uint16_t screenWidth = 256;
    static const uint16_t screenHeight = 240;

    uint8_t buffer[screenHeight][screenWidth][3];
};

【讨论】:

  • 好吧,我的错,但为什么它仍然不起作用?它不应该截断值并将其用作常量吗?编译器错误消息至少可以说是模糊的
  • 零,这就是原因
  • 它确实“截断” - 但归零! (如果您将任一文字声明为 0,您将收到相同的错误消息。)
【解决方案3】:

你的问题是uint8_t

static const uint8_t screenWidth = 256;//effectively 0

溢出,正好是一个大圆零。见

要修复,请切换到例如。 size_t(也更适合大小)

【讨论】:

  • 你链接整数溢出,但这是无符号整数溢出,一个是(仍然)UB,另一个不是
  • @idclev463035818 我相信该标签适用于两者。
  • 是的,但这里的区别很重要。没什么大不了的,只是觉得值得一提
  • @idclev463035818 它只是算术运算中的UB。从整数类型到有符号整数类型的转换在 C++20 中是模 2^N 并且之前是实现定义的。根本称它为“溢出”可能是不准确的。
  • @walnut 感谢您的澄清。今天学到了一些东西:检查;)
猜你喜欢
  • 1970-01-01
  • 2011-05-07
  • 2016-10-28
  • 2023-04-08
  • 1970-01-01
  • 2011-05-25
  • 1970-01-01
  • 2012-01-27
  • 2011-06-04
相关资源
最近更新 更多