In C, declaring an array size using a variable, even if it is a const
variable, is NOT allowed. Ex: 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;
}
Output:
$gcc -o main *.c
main.c:5:5: error: variably modified ‘a’ at file scope
int a[SIZE];
^
In C++, however, it runs just fine.
Run the above code in C++.
Output:
$g++ -o main *.cpp
$main
1, 2
To make it run in C, you must use #define
instead of a variable. ie:
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 have no other choice. But in C++ you clearly have at least 2 choices, so is one better than the other? Is there a risk to using one over the other?
Related:
- variably modified array at file scope in C
- static const vs #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.
- https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es31-dont-use-macros-for-constants-or-functions
- "static const" vs "#define" vs "enum"
- https://en.wikipedia.org/wiki/Variable-length_array#C99
I like your question! C++ is evolving to a language where you no longer need
#define
. Depending on the version, you can replace other constructs. Their are several reasons for this, including problems with IDEs, unexpected replacement of variable names of enum values with other constants, (Don't combine ERROR and ) and the absence of namespaces as this is all preprocessor replacement.For this example, you create a C-style array, which requires a constant. Writing
const int SIZE = 2
however does not create a constant, it creates a immutable variable. This can be used in a lot of ways and can be initialized with almost any code, including something you calculated from reading a file.The thing you are searching for is
constexpr
. The keyword that promotes your variable to a compile time constant and limits the initialization options to all code that can be executed at compile time. So: constants, calculations with them and constexpr functions that group these calculations. If you want to know more about it, Google for constexpr (or use a different search engine).Note C++11 is required for constexpr, C++14 is recommended when you want to write constexpr functions. For constexpr standard library functions, you'll have to wait C++20, if I remember well.
Because
SIZE
was defined as aconst
variable. In C, unlike C++const
values are not true constants. They are stored in memory and can be referenced and modified indirectly (by modifying the contents in memory). That's why, in C++ there isconst
that would allowconst int SIZE = 2;
to work, but evenconst
is not enough in C.C11-§6.7.9/3:
Preprocessor macro replace at compile time, that's why it's work fine.
Reference Link : https://stackoverflow.com/a/35162075/5612562
It would be good to follow Scott Meyer's advice in this matter. From his book "Effective C++":
Item 2: Prefer consts, enums, and inlines to #defines.
Summary of the item adapted to your example.
Also refer to "Item 3: Use const whenever possible." for more info on its usage and exceptions to its usage.
So to answer your question in the title:
No, it is NOT a bad practice to specify an array size using a variable instead of
#define
in C++.