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?
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.
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.
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++.
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.
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
.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With