-1

Why does the following work:

#define MAX 100
char MY_ARRAY[MAX];

But the following does not:

int MAX_2 = 200;
char MY_ARRAY_2[MAX_2];

Here is an example from Compiler Explorer. The interesting thing to me is before defining the final char array things look like it should work -- all integers are defined in data...

enter image description here

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
David542
  • 104,438
  • 178
  • 489
  • 842
  • 1
    A quirk of C. It's not obliged to remember integer values unless they fit the definition of an integer constant. – Petr Skocik Jan 12 '21 at 20:41
  • @PSkocik thanks. Could you please elaborate on that a bit on what that means, etc. (I'm a newbie to C). – David542 Jan 12 '21 at 20:42
  • 1
    The size of global arrays has to be a constant. Variable-length arrays can only be local variables. – Barmar Jan 12 '21 at 20:42
  • @Barmar but it doesn't work either if I do `const int` – David542 Jan 12 '21 at 20:44
  • It is just the way the language is defined, a variable is not a constant (even if declared `const`). Another way to declare constants is with `enum` . – M.M Jan 12 '21 at 20:44
  • 2
    `const int` is a variable, you're just not allowed to reassign it. – Barmar Jan 12 '21 at 20:45
  • Integer literals (e.g., `42`), enum constants (e.g., `foo` after `enum{foo=42};`), arithmetic expression based on either of the previous (e.g., `(42*2)`) and macros that expand to either of the previous are considered integer constants and C requires them in certain contexts such as static array sizes, case labels, bit field widths or enum constant values. – Petr Skocik Jan 12 '21 at 20:46
  • @David542, contrary to your apparent belief, having a `const`-qualified type does not make an object a "constant" in the relevant sense. – John Bollinger Jan 12 '21 at 20:46
  • @M.M -- thanks for pointing that out! Yes it does work for me when defined that way: `enum {MAX_3=200};` `char MY_ARRAY_2[MAX_3];` – David542 Jan 12 '21 at 20:47
  • 3
    This topic is covered in many other posts. Suggest you search using the exact error message. For example: [here](https://stackoverflow.com/questions/1712592/variably-modified-array-at-file-scope) and [here](https://stackoverflow.com/questions/13645936/variably-modified-array-at-file-scope-in-c). – kaylum Jan 12 '21 at 20:47
  • @JohnBollinger I see -- thanks for pointing that out. Would you care to elaborate a bit further, perhaps in an answer? – David542 Jan 12 '21 at 20:47
  • 1
    Since it does not work, the compiler spits out an error message. Error messages are great to search. And if you don't find what you're looking for, it's great to include the error message in the question so it becomes more searchable for future readers. – klutt Jan 12 '21 at 20:51
  • I'm afraid not, @David542, because the question is a dupe. I see that you seem to focus most of your attention on Python and related technologies, at least here on SO. I suspect that that orientation colors your expectations, even though I'm sure you already appreciate that C is *very* different language. At least, expecting the second of your two approaches to work seems consistent with that. It seems a rather Pythonic expectation for how type declarations might work in a language such as C that actually has declared types. – John Bollinger Jan 12 '21 at 20:57
  • It isn't a good duplicate target (it is for Objective-C). The one for C is *[Variably modified array at file scope in C](https://stackoverflow.com/questions/13645936/variably-modified-array-at-file-scope-in-c)*. – Peter Mortensen Jul 29 '23 at 09:11

1 Answers1

2

In the declaration of the array

#define MAX_VALUE 100
char MY_ARRAY[MAX_VALUE]; 

there is used an integer constant expression for the size of the array.

In this declaration

int MAX_VALUE=100;
char MY_ARRAY[MAX_VALUE];

there is declared a variable length array. But you may not declare a variable length array with the static storage duration (in particularly in a file scope). You could declare such an array in a block scope if the compiler supports variable length arrays.

Even if you will use the qualifier const in the declaration of the variable MAX_VALUE like

const int MAX_VALUE = 100;

it will not produce an integer constant expression according to its definition in the C Standard.

Instead you could write

enum { MAX_VALUE = 100 };
char MY_ARRAY[MAX_VALUE];

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.

And (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.)

and

2 If an identifier is declared as having a variably modified type, it shall be an ordinary identifier (as defined in 6.2.3), have no linkage, and have either block scope or function prototype scope. If an identifier is declared to be an object with static or thread storage duration, it shall not have a variable length array type.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335