Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why the size of array as a constant variable is not allowed in C but allowed in C++?

Tags:

c++

c

I tried to write a c program as below?

const int x = 5;

int main()
{
    int arr[x] = {1, 2, 3, 4, 5};
}

This is giving warnings when I tried to compile with gcc as below.

simple.c:9: error: variable-sized object may not be initialized.

But the same is allowed in C++. When I pass x as array size, why x is not treated as constant?

like image 265
kadina Avatar asked Sep 18 '14 00:09

kadina


People also ask

Can array size be a variable in C?

Variable length arrays is a feature where we can allocate an auto array (on stack) of variable size. It can be used in a typedef statement. C supports variable sized arrays from C99 standard.

Can the size of an array be declared at runtime in C?

No. In an array declaration, the size must be known at compile time. You can�t specify a size that�s known only at runtime.

What is the size of constant variable in C?

In C++ the size of the character constants is char. In C the type of character constant is integer (int). So in C the sizeof('a') is 4 for 32bit architecture, and CHAR_BIT is 8. But the sizeof(char) is one byte for both C and C++.

Why are variable length arrays bad in C?

The biggest problem is that one can not even check for failure as they could with the slightly more verbose malloc'd memory. Assumptions in the size of an array could be broken two years after writing perfectly legal C using VLAs, leading to possibly very difficult to find issues in the code.


2 Answers

In C const doesn't mean "constant" (i.e., evaluable at compile time). It merely means read-only.

For example, within a function, this:

const int r = rand();
const time_t now = time(NULL);

is perfectly valid.

The name of an object defined as const int is not a constant expression. That means that (in C prior to C99, and in all versions of C++) it can't be used to define the length of an array.

Although C99 (and, optionally, C11) support variable-length arrays (VLAs), they can't be initialized. In principle, the compiler doesn't know the size of a VLA when it's defined, so it can't check whether an initializer is valid. In your particular case, the compiler quite probably is able to figure it out, but the language rules are designed to cover the more general case.

C++ is nearly the same, but C++ has a special rule that C lacks: if an object is defined as const, and its initialization is a constant expression, then the name of the object it itself a constant expression (at least for integral types).

There's no really good reason that C hasn't adopted this feature. In C, if you want a name constant of an integer type, the usual approach is to use a macro:

 #define LEN 5
 ...
 int arr[LEN] = {1, 2, 3, 4, 5};

Note that if you change the value of LEN, you'll have to re-write the initializer.

Another approach is to use an anonymous enum:

 enum { LEN = 5 };
 ...
 int arr[LEN] = {1, 2, 3, 4, 5};

The name of an enumeration constant is actually a constant expression. In C, for historical reasons, it's always of type int; in C++ it's of the enumeration type. Unfortunately, this trick only works for constants of type int, so it's restricted to values in the range from INT_MIN to INT_MAX.

like image 62
Keith Thompson Avatar answered Sep 20 '22 13:09

Keith Thompson


When I pass x as array size, why x is not treated as constant?

Because in C, constant expressions can't involve the values of any variables, even const ones. (This is one reason why C is so dependent on macro constants, whereas C++ would use const variables for the same purpose.)

On the other hand, in C++, x would certainly be a constant expression if x is declared as const int x = 5;.

If your question is why C++ is so much more liberal than C when it comes to constant expressions, I think it's to support metaprogramming, and allow complex computation to be performed at compile time using templates.

like image 23
Brian Bi Avatar answered Sep 18 '22 13:09

Brian Bi