0

Can a function's argument be used in a later argument? Is this bad form?

void print(int n, int m, int matrix[n][m])
{
    for (int i=0; i<n; i++) {
        for (int j=0; j<m; j++) {
            printf("%i ", matrix[i][j]);
        }
        printf("\n");
    }
}

int main (void)
{
    int matrix[2][2] = {{1,3},{3, 5}};
    print(2, 2, matrix);
}

In playing around with passing 2-D arrays to functions, I've found a bit of a trick which I'm not sure I trust. It compiles (gcc -Wall -std=c99) and runs, so is there any issue with it?

Furthermore, does this imply that the arguments are read and assigned sequentially from left to right?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
arbenton
  • 21
  • 2
  • what trick are you talking about? – artm Feb 20 '16 at 03:05
  • Look at the argument's array indices in the definition of "print". – arbenton Feb 20 '16 at 03:06
  • there isn't any trick in there - apart from you can write `int matrix[][m]` instead – artm Feb 20 '16 at 03:08
  • Nothing unusual or unexpected. – artm Feb 20 '16 at 03:09
  • I've never seen that before. – jamieguinan Feb 20 '16 at 03:14
  • Could you explain this? The classic textbook example that passes array and length goes (int array[], int length), or the pointer equivalent, rather than including the actual size. Why is this? – arbenton Feb 20 '16 at 03:16
  • That is because it's 1D array, for 2D array you must include the size of the 2nd dimension anyway. Note that `C` treats 2D array simply as a serial of elements, so it must know the 2nd dimension when you pass it to a function, whereas the 1st dimension is not needed when passing. – artm Feb 20 '16 at 03:24
  • 1
    @arbenton: The classic convention is backwards compared with what C99 (and C11) requires for arrays — it wants the sizes to be known before the array itself is declared/defined. That seems reasonable to me. The original convention still works for arrays where the size is not variably modified (VM) — even if the size varies between calls. But where the shape of the whole array can be changed between calls (e.g. between short and wide one time and long and narrow the next), the sizes must be known before the array itself is defined. – Jonathan Leffler Feb 20 '16 at 03:30
  • From testing, I've found this only works from left to right. However, I've found an example (http://stackoverflow.com/questions/3911400/how-to-pass-2d-array-matrix-in-a-function-in-c) showing otherwise. Is this a matter of standard? – arbenton Feb 20 '16 at 03:37
  • @arbenton: The accepted answer to the question you cross-reference does not cover VLAs so it has nothing germane to say about this question. – Jonathan Leffler Feb 20 '16 at 03:38
  • 1
    You ask "does this imply that the arguments are read and assigned sequentially from left to right?" The answer is "No". The VLAs must have the dimension defined lexically before the VLA itself, but that imposes no ordering on the arguments on the stack. To the extent that the function body must design its array access using the size variables, then those have to be processed before local VLAs are created (so that the right amount of space is allocated), and access to the argument VLAs must be tuned by the size values before actually accessing the array elements. But the 'As If' rule applies. – Jonathan Leffler Feb 20 '16 at 03:42
  • @arbenton I tried compiling the code from that question. It generates 4 errors. Try it yourself, and/or read the comments below that answer. – user3386109 Feb 20 '16 at 03:55

1 Answers1

1

The matrix argument is a variable length array (VLA). VLAs were introduced in C99, but support for VLAs is optional in C11. So if it compiles, you're good. But don't expect it to compile everywhere, e.g. compilers for embedded systems may choose not to support VLAs.

For official documentation see section 6.7.6.2 Array declarators which contains these examples in paragraph 10:

enter image description here

user3386109
  • 34,287
  • 7
  • 49
  • 68