3

I get a compile error when I try to assign the struct with the array size of a global variable which the user will input in at the command line, and then pass the value back to the variable that was declared globally.

Here is just sample code:

#include <stdlib.h>
#include <stdio.h>

int Type;

struct list_el {
    int val;
} list1[Type];

struct list_el item;

int main() {
    Type = 10; // Just a sample
}

Error:

variable modified at file scope Struct C

Is there a way to fix the problem? I need it to work globally.

5
  • list1[Type] - Now assume you're a compiler, what do you know about Type? Commented Oct 17, 2013 at 8:12
  • I'm genuinely interested in what actual problem this design is trying to solve. Commented Oct 17, 2013 at 8:13
  • it part of big program I try to make but struct list_el list1[Type] need to be globally to access from other function Commented Oct 17, 2013 at 8:19
  • Does the error message actually contain "Struct" (uppercase "S"). It isn't in the code. Commented Jul 29, 2023 at 11:05
  • OK, the OP has left the building: "Last seen more than 2 years ago". Perhaps somebody else can chime in? Commented Jul 29, 2023 at 11:07

4 Answers 4

4

When declaring an array, you need a compile-time constant for the size, which Type isn't.

If you want to allocate during runtime, use pointers and malloc.


Well, actually you can have non-constant variables for array size, it's called variable-length arrays. The problem with using a global variable for the size is that global variables are initialized to zero, so what you are doing is actually creating an array with zero elements, but only if the variable Type is initialized before the array is created.

Sign up to request clarification or add additional context in comments.

1 Comment

@AlterMann not at global-scope.
3

Your code is not valid: you can't first declare an array using a variable as the size, and then assign to the variable.

Or, you can, but the array certainly won't magically change.

Also, it's very strange to have the variable and array be global.

You should probably just do:

int main(void)
{
  int num;

  printf("enter size:\n");
  if(scanf("%d", &num) == 1 && num > 0)
  {
    struct list_el list1[num];

    /* here, work with the array. */
  }
}

Note that using a variable like this is a C99 feature.

1 Comment

I need struct list_el list1[num]; to be globally
2

If you want both the list and its magnitude Type to be global and dynamically allocated, you need to do just that: dynamically allocate.

#include<stdlib.h>
#include<stdio.h>

int Type;

struct list_el {
    int val;
} *list;

int main() 
{
    Type = 10;

    list = malloc(Type * sizeof(*list));

}

That said, seriously question whether you need these globally. If your compiler supports it you can use a local variable-length array (VLA). It is a C99 optional feature, testable by checking if __STDC_NO_VLA__ is not defined.

7 Comments

So this code will assign Type vaiable (10) to size of struct list_e1 array to 10 and be able to accessed that array globally
@user1611864 this will allocate enough memory for Type number of struct list_el elements, assigning the resulting memory address to the pointer list, which can then be used as list[n] for all n between 0 and the value of Type-1 at the time of the allocation. This does NOT magically grow or shrink the allocated buffer size just by changing Type later on. If you want that, see, and understand realloc().
@user1611864 ...and it doesn't have to be global. You can make your "other functions" take a pointer and size as parameters. I don't advise doing this globally, but if you're set on doing so, this is one way.
For the __STDC_NO_VLA__ you are not exactly right. This is a mandatory feature for C99 which became optional with C11. So compilers that implement this feature test macro are probably not yet very common.
@JensGustedt C99 6.10.8.3 Conditional feature macros, " __STDC_NO_VLA__ The integer constant 1, intended to indicate that the implementation does not support variable length arrays or variably modified types". Or was that just left in the standard by mistake?
|
0

You could use alloca() in main to stack-allocate the memory.

struct list_el {
  int n;
} *list;
static int Type;

int main(int argc, char** argv) {
  Type = argc;
  list = alloca(sizeof(struct list_el) * Type);

  // use list...
}

The memory will stay in-scope until main() returns. I don't know what happens in an atexit() callback. That's an interesting question.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.