4

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?

Eric Postpischil
  • 168,892
  • 12
  • 149
  • 276
Zaratruta
  • 1,637
  • 2
  • 18
  • 23

3 Answers3

7

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

Jonathan Leffler
  • 698,132
  • 130
  • 858
  • 1,229
  • About interleaving statements and declarations, you could still have nested scope blocks in `{}`, and you could declare new variables at the beginning of any such block, so it would have been possible to read size, then declare VLA of that length in a nested block after that. ...or am I mistaken? – hyde Apr 15 '19 at 21:14
  • @hyde: yes, you could define variables at the start of any statement block. In C89/C90, you could not have a variable-length array even if the size was determined in an outer block and the array defined in an inner blcok; the dimensions of an array had to be fully determinate at compile time (by definition using constants for all the dimensions, or by initialization to allow the first dimension to be unspecified). The only way to dynamically size an array was via dynamic memory allocation — `malloc()` et al. The rules all changed in C99. – Jonathan Leffler Apr 15 '19 at 21:18
  • You may want to mention that ANSI has been adopting the more recent ISO/IEC standards and not just ISO 9899:1990. This just perpetuates the confusion that ANSI-C refers just to first revision. https://stackoverflow.com/a/4232714/1028434 – fdk1342 Apr 15 '19 at 22:20
  • @Fred: I've added a paragraph to emphasize that national standards bodies such as ANSI, BSI, DIN adopt ISO standards. Whatever may be the case in other areas of the world affected by ISO and ANSI, in the C world, 'ANSI C' refers to C89 and ISO C can be used to contrast the later standards. At one level I agree with you; at another level, I think you are pushing against a close to immovable object. – Jonathan Leffler Apr 15 '19 at 22:42
  • Yep (regarding my earlier comment), but the wording of first paragraph could be changed, because you *could* put the declaration after the scanf by adding a nested block. I'm rising this point, because many seem to think you had to define all variables at the start of a *function*. – hyde Apr 16 '19 at 04:48
  • @hyde: I'm not convinced the extra detail is necessary, but I've added verbiage to cover your point. – Jonathan Leffler Apr 16 '19 at 04:57
0

ANSI-C (C89) does not allow initialize an array using a variable.

For example:

  int x = 5;
  int ia[x];

This above example is illegal. ANSI-C restricts the array intialization size to be constant. However you can use macros to define the length of an array.

Example:

    #define MAX_ARRAY_SIZE 5
    int ia[MAX_ARRAY_SIZE];
colxi
  • 6,515
  • 2
  • 40
  • 40
  • 2
    erm C99 allows variable length arrays. – Jean-François Fabre Apr 15 '19 at 20:25
  • 1
    the answer is incomplete and not mentionning C99 VLAs. Question is a clear dupe anyway. – Jean-François Fabre Apr 15 '19 at 20:33
  • He asks very clearly : "Is this allowed in the so called ANSI C?" My answer focus in that specific question. If you think a more extensive answer can be provided, you can write your own. – colxi Apr 15 '19 at 20:38
  • 1
    According to the ANSI website: `The Current C Programming Language Standard – ISO/IEC 9899:2018 (C18)`. So when people refer to the ANSI standard it isn't just limited to C89. – fdk1342 Apr 15 '19 at 20:55
  • 1
    @Fred: In common parlance, partially enforced by the GCC compiler, ANSI standard means the C89 standard X3.158-1989, released before the ANSI/ISO 9899-1990 standard was released (marked with "revision and redesignation of ANSI X3.159-1989"). The main difference was the section numbers in the ANSI and ISO standards. GCC encourages this confusion because the option `-ansi` is equivalent to `-std=gnu90`, and so many people regard "ANSI C" as the C89 or C90 standard — they're effectively equivalent standards. Quibbling otherwise doesn't actually help anyone very much. – Jonathan Leffler Apr 15 '19 at 21:02
  • 1
    @JonathanLeffler Maybe you think it's common, that's fine, but I disagree. The common practice I've seen is that ANSI-C refers to the standard as opposed to additional extensions supported by the compiler. Also according to GCC manual `-ansi` is equivalent to `-std=c90` NOT `-std=gnu90`. So even here ANSI refers to not using GNU dialect and certain GNU extensions. I would have to say that your comment isn't very helpful either. – fdk1342 Apr 15 '19 at 21:49
  • @Fred: It's best if we simply agree that we disagree, then. – Jonathan Leffler Apr 15 '19 at 21:51
0

This kind of array, called variable length array was added in C99. Check out this nice article about modern C programming:

https://matt.sh/howto-c

  • 1
    +1 for having a correct (if pithy) answer, -1 for the link to a top-level entry point for a wide-ranging resource as opposed to pointing to (1) a narrower location within a resource; or (2) letter-and-verse of the relevant spec (or finding something licensed to be quotable in-answer and thus able to survive link breakage). – Charles Duffy Apr 15 '19 at 20:30
  • That's a nice observation. Pointing to the specific spec in the language reference would be more reliable for the readers. Writing the tip down for my future answers. – marcelodmmenezes Apr 15 '19 at 20:35