-1

The following code snippet is illegal in C, but works perfectly in C++.

Why can we not use a const to help initialize the length of an array in C?

#include <stdio.h>
#include <string.h>

int main () {

   const int size = 6;
   char name[size] = "hello";
   printf("%s", name);

   return 0;
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
J.Doe
  • 31
  • 4
  • Using `size` for its value requires getting the value of an object, the `const int size = 6` that was defined previously. Nominally, this value is stored in memory that does not exist yet—the `size` object is something defined for the running program, not for the compiler *per se*. As C developed, compilers could evaluate simple expressions that used built-in operators but did not require calling functions or using the values of objects. So its rules for constant expressions followed that. It has not been judged worthwhile to add support for this in C. – Eric Postpischil Nov 08 '20 at 21:10
  • You example is actually valid from C99: https://en.wikipedia.org/wiki/Variable-length_array#Implementation – tuket Nov 08 '20 at 21:18
  • Instead of variable length array, simply use `malloc` - and you will not have such questions. – i486 Nov 08 '20 at 21:22

2 Answers2

1

In C, an array whose size is not an integer constant expression is a variable length array, and such arrays cannot be initialized because their size is not know at compile time.

A variable with the const qualifier does not count as an integer constant expression in C, so that makes name a variable length array resulting in the error when you attempt to initialize it.

C++ on the other hand has different rules for constants. A const qualified variable whose initializer is an integer constant expression is considered a compile time constant in C++ and therefore an array using such a variable to specify its size may be initialized.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • What would happen if I attempted to make this a variable length array in C++? Suppose I had the value of size equal to the return of a function that is intended to be random, instead of the number 6 in my example. Such as, `const int size = randint()`. This would not be a compile-time constant, but needs to find the value at run-time. – J.Doe Nov 08 '20 at 21:18
  • @J.Doe The C++ standards do not allow for VLAs, although some compilers such as gcc support it as an extension. – dbush Nov 08 '20 at 21:22
-1

The C Standard allows C compilers to support variable length arrays. The const qualifier for a variable used as an array size does not make a constant integer expression in C opposite to C++.

From the C Standard (6.6 Constant expressions)

6 An integer constant expression117) shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, and floating constants that are the immediate operands of casts. Cast operators in an integer constant expression shall only convert arithmetic types to integer types, except as part of an operand to the sizeof operator.

The word integer or character constants in this quote means literals.

As for variable length arrays then ( The C Standard 6.7.6.2 Array declarators)

4 If the size is not present, the array type is an incomplete type. If the size is * instead of being an expression, the array type is a variable length array type of unspecified size, which can only be used in declarations or type names with function prototype scope; such arrays are nonetheless complete types. If the size is an integer constant expression and the element type has a known constant size, the array type is not a variable length array type; otherwise, the array type is a variable length array type. (Variable length arrays are a conditional feature that implementations need not support; see 6.10.8.3.)

Some C++ compilers can have their own language extensions that allow also to use variable length arrays in a C++ program. But it is not a X++ Standard feature.

Even if a C++ compiler supports variable length arrays it is better to use the standard class template std::vector instead of variable length arrays.

Pay attention to that you may not initialize a variable length arrays in C when they are declared. And variable length arrays have the automatic storage duration. You may apply the sizeof operator to variable length arrays that is evaluated at run-time.

Here is a demonstrative program of using variable length arrays.

#include <stdio.h>

void f( size_t, size_t, int[][*] );

void f( size_t m, size_t n, int a[][n] )
{
    for ( size_t i = 0; i < m; i++ )
    {
        for ( size_t j = 0; j < n; j++ )
        {
            a[i][j] = n * i + j;
        }
    }
}

void g( size_t, size_t, int[][*] );

void g( size_t m, size_t n, int a[][n] )
{
    for ( size_t i = 0; i < m; i++ )
    {
        for ( size_t j = 0; j < n; j++ )
        {
            printf( "%2d ", a[i][j] );
        }
        putchar( '\n' );
    }
}

int main(void) 
{
    const size_t m1 = 3, n1 = 3;
    int a[m1][n1];
    
    f( m1, n1, a );
    g( m1, n1, a );
    
    putchar( '\n' );
    
    const size_t m2 = 4, n2 = 5;
    int b[m2][n2];
    
    f( m2, n2, b );
    g( m2, n2, b );
    
    putchar( '\n' );
    
    return 0;
}

The program output is

 0  1  2 
 3  4  5 
 6  7  8 

 0  1  2  3  4 
 5  6  7  8  9 
10 11 12 13 14 
15 16 17 18 19
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335