0

My book states: "The expression used to specify the length of" a variable array "could refer to variables outside the function". I guess this is what the book means:

int main(void)
{
   int xternal = 3;
   int variable_array[xternal];
   function(variable_array);
}

void function(int variable_array[xternal])
{
   ...
}

I understood that variables outside the function are invisible to it. Am I wrong?

user3646717
  • 1,095
  • 2
  • 12
  • 21
  • I tried to correct it, now I hope its error free. – user3646717 Apr 10 '15 at 04:18
  • The updated code in `main()` could be what it means, although it's more likely that `int xternal` would be before `main`. Also, be aware that `xternal` in the function prototype [is ignored](http://stackoverflow.com/questions/22677415/why-do-c-and-c-compilers-allow-array-lengths-in-function-signatures-when-they/) – M.M Apr 10 '15 at 04:21
  • 1
    That can't work; `xternal` is not a known identifier in the scope of `void function(int variable_array[xternal])`. If you had `int xternal = 3; int main(void) { … }` then you might be in with a chance; I'd have to look at the standard to see what it says. But as written, the answer is unequivocally "No". – Jonathan Leffler Apr 10 '15 at 04:22

2 Answers2

2

You can reference variables outside of a function, but not ones within other functions

int xternal = 3;

int main(void)
{
   int variable_array[xternal];
   function(variable_array);
}

void function(int variable_array[xternal])
{
   ...
}
0

I presume you are referring to variable-length-array parameters of C99.

I think your textbook is trying to say that you can use as a length specifier not only other arguments of a function, e.g.:

void f(int array_len, char array[array_len]);

but something outside but still visible, like global variable:

int some_value;

void f(char array[some_vaue]);

Keep in mind - this does not necessarily mean compiler will do array bounds checks for you. This is useful when you use multidimensional arrays to navigate on inner dimensions.

So instead of this code:

 int *arr = malloc(sizeof(int)*NROWS*NCOLS);

 void f(int *a)
 {
      int row, int column;
      ...calculate row, column
     int value = a[row*NCOLS+column];
     ...
 }

you will write:

 int arr[NROWS][NCOLS];

 int get_array_cols()
 {
     return NCOLS;
 }
 int array_rows=NROWS;//or calculate...

 void f(int a[array_rows][get_array_cols()])
 {
      int row, int column;
      ...calculate row, column
      int value=a[row][column];
      ...
 }

as you can see anything couldbe there.

Basically, when compiler knows how to get value for dimensions, it can automatically prepare this expression: a[row*NCOLS+column]; (row*NCOLS). For example in my last case, having dimensions hint, it will automatically compile a[row][col] into: a[row*get_array_cols()+col].

fukanchik
  • 2,811
  • 24
  • 29
  • The book didn't specify global variables, but now I think it could be right in that sense. Thank you! – user3646717 Apr 10 '15 at 04:37
  • `void f(int array_len, char array[array_len]);` is not a VLA specifier. The value inside the `[]` is ignored, this is the same as `void f(int array_len, char array[]);`. The `array_len` would only be written there for self-documentation purposes. The type of `array` is `char *`. – M.M Apr 10 '15 at 05:36
  • `a[row][col]` is not transformed into `a[something]`. You're trying to describe `((int *)a)[something]`. – M.M Apr 10 '15 at 05:50