In C, declaring an array size using a variable, even if it is a const variable, is not allowed. Example: this fails to compile in C:
#include <stdio.h>
const int SIZE = 2;
int a[SIZE];
int main()
{
a[0] = 1;
a[1] = 2;
printf("%i, %i", a[0], a[1]);
return 0;
}
gcc -o main *.c
Output:
main.c:5:5: error: variably modified ‘a’ at file scope
int a[SIZE];
^
In C++, however, it runs just fine.
g++ -o main *.cpp
main
Output:
1, 2
To make it run in C, you must use #define instead of a variable. I.e.:
This runs just fine in C or C++:
#include <stdio.h>
#define SIZE 2
// const int SIZE = 2;
int a[SIZE];
int main()
{
a[0] = 1;
a[1] = 2;
printf("%i, %i", a[0], a[1]);
return 0;
}
So, in C++ I've almost always used a variable, rather than #define, to declare my array sizes. I just make the array size variable const and it's all good! Recently I started doing a lot of microcontroller programming in pure C, however, and when I ran into this error and figured out the problem, a senior developer told me it's bad practice to use anything but #define-ed constants (or maybe hard-coded numbers) to declare array sizes.
Is this true? Is it bad practice in C++ to use const variables instead of #define when specifying array sizes? If so, why?
In C, apparently you're stuck with #define: you don't have any other choice. But in C++ you clearly have at least two choices, so is one better than the other? Is there a risk to using one over the other?
Update: here's my own answer (added 6 Oct. 2023)
This is what constexpr is for in C++, so this is the best way in C++:
constexpr int SIZE = 2;
int a[SIZE];
Unlike const, which could be a run-time limitation on variable usage and modification, constexpr variables must be known statically at compile-time. They are the right way to do this in this case.
Related:
- Variably modified array at file scope in C
static constvs#define<-- this is a solid question and very helpful. It is most definitely related to my question, but my question is *not a duplicate because although they are both about const vs #define, my question is a very special case where one of the options doesn't even work in a language which is regularly considered to be a subset of C++. That's pretty unusual, and makes my question a more narrow subset which fits within the broad scope of this other question. Therefore, not a duplicate.- C++ Core Guidelines, ES.31: Don't use macros for constants or "functions"
- "static const" vs "#define" vs "enum"
- Variable-length array, C99
#define": No, there is the 'enum' trick.