Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In which versions of the C standard are variable length arrays not part of the language, required, or optional?

Tags:

c

Let us consider the following code:

#include <stdio.h>

int main(){
    int size,i;
    scanf("%d",&size);
    int x[size];

    for(i=0;i<size;i++){
        x[i] = i;
    }

    for(i=0;i<size;i++){
        printf("%d\n", x[i]);
    }

    return 0;
}

I think that there are versions in that we cannot declare an array using a variable for defining its size, like in:

int x[size];

But I'm not sure about which version is. This is allowed in the so called ANSI C?

like image 751
Zaratruta Avatar asked Mar 04 '23 03:03

Zaratruta


2 Answers

In C89/C90, you can't interleave declarations and statements, such as putting the int x[size]; declaration (definition) after the scanf() — even if you change the dimension to a compile time constant. In C89/C90, declarations within a function must appear at the start of a compound statement (immediately after the { and before the first statement within the compound statement; compound statements can be nested within a function body).

In C89/C90, you cannot use a variable length array — so the int x[size]; definition is not legal because size is not a compile time constant.

C99 compilers are required to support both declarations at (almost) arbitrary points in a function (they still can't be preceded by a label) and variable length array (VLA) definitions.

C11 compilers are required to support variable definitions (almost) anywhere in a function. C11 compilers may optionally support VLAs (§6.10.8.3 Conditional feature macros and §6.7.6.2 Array declarators), and should define __STDC_NO_VLA__ if they do not support them.

C18 is equivalent to C11 in all aspects of this discussion.

Just for the record:

  • C89 is ANSI X3.159-1989
  • C90 is ISO 9899-1990 — the ANSI version of which was marked with "revision and redesignation of ANSI X3.159-1989". The primary difference was in the section numbers for the language and the library.
  • C99 is ISO/IEC 9899:1999
  • C11 is ISO/IEC 9899:2011
  • C18 is ISO/IEC 9899:2018

Of course, the only unusual thing about X3.159-1989 was that it was published by ANSI before there was an ISO standard. However, ANSI has adopted each subsequent ISO standard too, as have other national standards bodies such as BSI (British Standards Institute) and DIN (Deutsches Institut für Normung or German Institute for Standardization).

There was also an Amendment 1 (to ISO 9899:1990) finalized in 1994 and published in 1995. That added headers and introduced digraphs and made sundry other changes. It is almost never considered separately, especially not now, 25 years later.

Note that GCC treats the -ansi option as equivalent to -std=c90, which can lead to confusion over terminology. ANSI originally published 'the ANSI C standard' a year or so before ISO did, but the intent was always to have a common standard, and ANSI endorsed the ISO 9899:1990 standard when it was published.

like image 135
Jonathan Leffler Avatar answered Mar 29 '23 23:03

Jonathan Leffler


This is how support for variable-length arrays (VLA) has changed in C over the years:

  • "C90" ISO 9899:1990+AMD1:1995 (aka "C89", ANSI X3.159, "ANSI C", AMD1 = "C95")

    No support for variable-length arrays.

  • "C99" ISO 9899:1999

    Variable length arrays were added as a new, mandatory feature.

  • "C11" ISO 9899:2011 and "C17" ISO 9899:2018 (aka "C18")

    Variable length arrays were relaxed to an optional feature. Compilers may define the macro __STDC_NO_VLA__ to indicate that they do not support any form of variable length arrays.

  • "C23" ISO 9899:20xx (aka "C2x") - upcoming ISO standard in 2023.

    Pointers to variable length arrays are once again made mandatory as in C99. __STDC_NO_VLA__ is now only used to indicate that variable array objects with automatic storage duration are not supported.


C11/C17 wording (6.10.8.3):

__STDC_NO_VLA__ The integer constant 1, intended to indicate that the implementation does not support variable length arrays or variably modified types.

C23 wording (n3054-5 draft 6.10.9.3):

The integer constant 1, intended to indicate that the implementation does not support variable length arrays with automatic storage duration. Parameters declared with variable length array types are adjusted and then define objects of automatic storage duration with pointer types. Thus, support for such declarations is mandatory.

like image 24
Lundin Avatar answered Mar 29 '23 22:03

Lundin