Array Initialization Use Const Variable in C++

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.


  1. 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



Leave a reply



Submit