2

When I try to declare a global two-dimensional array in C++ like so:

int maxX = 10;
int maxZ = 10;
SDL_Rect mapX[maxX][maxZ];

I get an error that says
error: variable-size type declared outside of any function

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
Shasaur Aura
  • 65
  • 1
  • 1
  • 9

5 Answers5

8

(At the first sight it looked to me as a "difference between C and C++ question". I could be mistaken though.)

Since you used non-constant values as array sizes, you are attempting to declare a variable-length array (VLA). C++ does not support VLAs at all, while C supports only local VLAs. The latter is exactly what the compiler is telling you in that error message. (And I believe this error message came from a C compiler, since C++ compiler would give you a completely different error.)

So, strictly speaking, you cannot declare such array either in C or in C++. While C language supports VLAs, they still have to be local. You are not allowed to declare VLAs with static storage duration in C.

In C++ all arrays have to have fixed pre-determined compile-time size. Which means that the array sizes have to be specified by compile-time constants. You used non-constant values instead, which is what caused the error.

In other words, in both C and C++ you are required to use constant expressions when specifying sizes for arrays with static storage duration (including so called "global" arrays).

In C++ in order to make your sizes constant you have to declare them with const

const int maxX = 10;
const int maxZ = 10;

In C this will not work, since in C const objects are not really constants in a sense that they don't form constant expressions. In C you'd have to use either

#define maxX 10
#define maxZ 10

or

enum {
  maxX = 10,
  maxZ = 10
};
AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
2

In C++, you cannot use a variable to define the size of an array, since the compiler needs to know at compile time where to assign the array's memory and how much memory it needs. Declaring maxX and maxZ as int makes them variables, and therefore unsuitable for array dimensions. However, if you declare them as const int, they will then be contants, and the compiler will know that those values will be fixed over the execution of your program, and it will allow their use to define array dimensions.

Therefore, this doesn't work:

int maxX = 10;
int maxZ = 10;
SDL_Rect mapX[maxX][maxZ]; // Not allowed

But this is fine:

const int maxX = 10;
const int maxZ = 10;
SDL_Rect mapX[maxX][maxZ]; // Allowed
M.M
  • 138,810
  • 21
  • 208
  • 365
Fred
  • 4,894
  • 1
  • 31
  • 48
1
static const int maxX = 10;
static const int maxZ = 10;
SDL_Rect mapX[maxX][maxZ];

works fine for me.


Note

It isn't generally good practise to use either globals, or raw arrays, or global raw arrays in general. Obviously I don't have enough context to comment on whether or not it is the right choice here.


Historical Note

Before modern constness, it was common to either enumerate or #define constants to make them work correctly in this situation.

Useless
  • 64,155
  • 6
  • 88
  • 132
  • Firstly, strictly speaking, in C++ `const` objects *always* worked in this context, while in C they *never* worked in this context and *still don't*. For this reason, I don't understand your "before modern constness" remark. There's no temporal separation here. Nothing really changed from "before". (Unless you see C++ as the modern successor and replacement of C. I personally don't.) – AnT stands with Russia Dec 25 '12 at 20:15
  • Secondly, your code "works fine" in C++ only, but the `static` part is redundant. In C++ `const` objects have static linkage by default. In C the `static` part makes a difference, but your declaration will not compile anyway, since in C `maxX` and `maxZ` are not constants. They cannot be used in static array declarations. – AnT stands with Russia Dec 25 '12 at 20:17
  • True: the question is tagged C++, but I'll address each separately if I have time. – Useless Dec 26 '12 at 01:59
0

I do not think so this is the correct way to use SDL_rect.

The syntax should be like

SDL_Rect rect = {0,0,10,10}

So you can do the following;

int maxX = 10;
int maxZ = 10;
SDL_Rect rect = {0,0,maxX,maxZ}
Taicho
  • 143
  • 5
0

Rather than C-style arrays, I would recommend the use of std::vector:

std::vector< std::vector<SDL_Rect> > mapX;
pmr
  • 58,701
  • 10
  • 113
  • 156
template boy
  • 10,230
  • 8
  • 61
  • 97