Array initialization use const variable in C++
Because the guys in the C++ committee decided so.
The technical reason is that the first expression that is used to initialize size
is a constant expression and it can be computed during compilation. This means that the compiler can also know how big the array is going to be and the allocation (in this case "reservation" may be a more appropriate term) can be done at compile time.
In the second case instead the expression is not a constant expression (given the C++ definition) and this revervation is not possible.
The fact that in the second case the value is indeed fixed by the time size
is initialized is totally irrelevant. The rules are base on the "kind of expression" and the second expression uses mutable variables and thus the compiler considers it non-constant.
Allowing the second form for compile-time initialization would require a flow analysis because it would need to distinguish between
int a = 2;
const int size = a;
and
int a = foo();
const int size = a;
where the expression involving size
is indeed identical.
In C, why can't a const variable be used as an array size initializer?
In C, a const
-qualified variable is not a constant expression1. A constant expression is something that can be evaluated at compile time - a numeric literal like 10
or 3.14159
, a string literal like "Hello"
, a sizeof
expression, or some expression made up of the same like 10 + sizeof "Hello"
.
For array declarations at file scope (outside the body of any function) or as members of struct
or union
types, the array dimension must be a constant expression.
For auto
arrays (arrays declared within the body of a function that are not static
), you can use a variable or expression whose value isn't known until runtime, but only in C99 or later.
- C++ is different in this regard - in that language, a
const
-qualified variable does count as a constant expression.
Const arrays in C
It means that each element of z
is read-only.
The object z
is an array object, not a pointer object; it doesn't point to anything. Like any object, the address of z
does not change during its lifetime.
Since the object z
is an array, the expression z
, in most but not all contexts, is implicitly converted to a pointer expression, pointing to z[0]
. That address, like the address of the entire array object z
, doesn't change during the object's lifetime. This "conversion" is a compile-time adjustment to the meaning of the expression, not a run-time type conversion.
To understand the (often confusing) relationship between arrays and pointers, read section 6 of the comp.lang.c FAQ.
It's important to understand that "constant" and const
are two different things.
If something is constant, it's evaluated at compile time; for example, 42
and (2+2)
are constant expressions.
If an object is defined with the const
keyword, that means that it's read-only, not (necessarily) that it's constant. It means that you can't attempt to modify the object via its name, and attempting to modify it by other means (say, by taking its address and casting to a non-const pointer) has undefined behavior. Note, for example, that this:
const int r = rand();
is valid. r
is read-only, but its value cannot be determined until run time.
Array size with const variable in C
Variable Length Arrays may have only automatic storage duration. VLAs were introduced in C99.
It is not allowed to declare a VLA with the static storage duration because the size of VLA is determinated at the run time (see below)
Before this Standard you can use either a macro like
#define SIZE 10
//...
int a[SIZE];
or a enumerator of an enumeration like
enum { SIZE = 10; }
//...
int a[SIZE];
By the way you may remove the const qualifier and just write
int size = 10;
instead of
const int size = 10;
(In C++ you have to use the const qualifier though in C++ there are no VLAs except that some compilers can have their own language extensions)
Take into account that the sizeof
operator for VLAs is calculated at the run-time instead of the compile-time.
How can I initialize an array of its length equal to the return of a const int method?
Drop the inline
and const
and add constexpr
specifier instead, to solve the issue:
constexpr int size() { return 256; }
now you can use it as array size like:
int arr[size()];
In C++ (not C) length of arrays must be known at compile time. const
qualifier only indicates that a value must not change during running time of a program.
By using constexpr
you will specify that the output of the function is a known constant, even before the program execution.
Error initializing array size using const static variable of class template
I 'd say to initialize the static member right in place.
static const size_t max_elem = 10;
More here.
Constant static members If a static data member of integral or
enumeration type is declared const (and not volatile), it can be
initialized with an initializer in which every expression is a
constant expression, right inside the class definition:
struct X {
const static int n = 1;
const static int m{2}; // since C++11
const static int k; };
const int X::k = 3; // Only this needs to be defined
Why we cannot create an array with a constant in c
In C:20
is a constant.unsigned int const size_of_list
is not a constant.
Title: "Why we cannot create an array with a constant in c" does not apply to this code.
const char* list_of_words[size_of_list] = {"Some", "Array"}; // Bad
An issue here (and the error message) is why a VLA cannot be initialized. That is answered here.
With a constant, array initialization works fine.
const char* list_of_words[20] = {"Some", "Array"}; // Good
Another issue is mistaking that const
makes an object a constant. It does not.
Alternative C code
int main(){
// unsigned int const size_of_list = 20;
#define size_of_list 20u
const char* list_of_words[size_of_list] = {"Some", "Array"};
for (unsigned int writing_index = 0; writing_index < size_of_list; writing_index ++)
;
return 0;
}
If you can specify the size in the array itself, then you can get it's size with the sizeof
operator. This may be better suited for having the compiler count up the size instead manual counting. When not using C99
VLAs, sizeof
also yields a compile-time constant.
#include <stddef.h> /* size_t */
int main(void) {
const char* list_of_words[] = {"Some", "Array"};
const char list_of_char[sizeof list_of_words
/ sizeof *list_of_words] = {'S','A'};
const size_t size_of_list
= sizeof list_of_words / sizeof *list_of_words;
for (size_t writing_index = 0;
writing_index < size_of_list; writing_index ++);
return 0;
}
Related Topics
Is the Order of Iterating Through Std::Map Known (And Guaranteed by the Standard)
Send and Receive a File in Socket Programming in Linux with C/C++ (Gcc/G++)
Is There Any "Standard" Htonl-Like Function for 64 Bits Integers in C++
How Are Iterators and Pointers Related
Redirecting Cout to a Console in Windows
Finding the Centroid of a Polygon
Convert Float to String with Precision & Number of Decimal Digits Specified
Std::Map Emplace Without Copying Value
How to Find and Replace String
Converting Multidimensional Arrays to Pointers in C++
How to Efficiently Display Opencv Video in Qt
Qt: Resizing a Qlabel Containing a Qpixmap While Keeping Its Aspect Ratio
(C/C++) How to Generate Executable File That Can Run on Both Windows and Linux
Differencebetween Crtbegin.O, Crtbegint.O and Crtbegins.O
Why Isn't 'Int Pow(Int Base, Int Exponent)' in the Standard C++ Libraries