2

I'm declaring a three-dimensional array as a class member, using static const class members as the first two bounds:

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

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

in Visual Studio 2019 I get the following (weird?) error:

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

if I resort to the "enum hack" in order to declare class-local compile time integer constants it works:

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

shouldn't the former example be C++11 compliant code? (I guess Visual Studio 2019 compiler is).

2
  • stackoverflow.com/q/13346879/1216776 Commented Mar 5, 2020 at 12:04
  • @stark const and constexpr have the same effect in this case. Integral types have special rules. Commented Mar 5, 2020 at 14:38

3 Answers 3

4

I think that an object of the type uint8_t is unable to contain the value 256.:)

Why not just to use the type size_t instead of the type uint8_t?

static const size_t screenWidth = 256;
static const size_t screenHeight = 240;
Sign up to request clarification or add additional context in comments.

1 Comment

@Luca In general it is a bad idea. From the C++ Standard "If the initializer-clause is an expression and a narrowing conversion (8.5.4) is required to convert the expression, the program is ill-formed" In your case the value is truncated to 0.
2

The problem you have is that, in the declaration:

static const uint8_t screenWidth = 256;

the value 256 is not valid for a uint8_t type (range is 0 thru 255), and it 'rolls over' to give an actual value of zero - which is invalid for an array dimension.

Make your dimension 'constants' bigger types, and your code will work:

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

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

3 Comments

ok, my bad, but why doesn't it work anyway? shouldn't it truncate the value and use that as constant? the compiler error message is obscure to say the least
it's a zero, that's why
It does 'truncate' - but to zero! (You will get the same error message if you declare either of the literals as 0.)
2

Your issue is with uint8_t

static const uint8_t screenWidth = 256;//effectively 0

overflows and is exactly a big round ZERO. See .

To fix, switch to eg. size_t (also more appropriate for sizes)

5 Comments

you link integer-overflow but this is unsigned integer overflow, one is (still) UB the other not
@idclev463035818 that tag is for both i believe.
yes, but here the distinction matters. Not a big deal, just thought it is worth mentioning
@idclev463035818 It is only UB in arithmetic operations. Conversion from integral type to signed integral type is modulo 2^N in C++20 and was implementation-defined before. Calling it "overflow" at all is probably inaccurate.
@walnut thanks for clarification. Learned something today: check ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.