I managed to succed to work with Variable length Arrays in C
and I have now the following:
#include
#include
i
Any way here
int (*foo(size_t row, size_t col))[3]
I have this[3]
which I'm not clear about how it works
Type declarations are most easily read from inside out. I'll start simple, and build up to your example. If you write
int foo[3];
or
int (foo)[3];
you are declaring foo
as an array of 3 int
s. The parentheses here serve a precedence-directing grouping function, just like in expressions, but they are unnecessary because the type is interpreted the same way in both cases.
If you write
int (*foo)[3];
you are declaring foo
to be a pointer to an array of 3 int
s. Equivalently, you can read that as saying that the thing foo
points to is an array of 3 int
s, with it being implicit that foo
is a pointer. In this case the parentheses are necessary; without them you would be declaring foo
as an array of 3 int *
.
If you write
int (*foo(size_t row, size_t col))[3];
you are declaring that foo
is a function taking two arguments of type size_t
, whose return value points to an array of 3 int
s.
and how can I make it possible on run time (of course only if is possible), something like
int (*foo(size_t row, size_t col))[SIZE]
.
If SIZE
is not a compile-time constant then you cannot do that. C2011 holds that
If an identifier is declared as having a variably modified type, it shall [...] have no linkage, and have either block scope or function prototype scope. [...]
(6.7.6.2/2)
In other words, because all functions have file scope and either internal or external linkage, function return types cannot be VLAs, pointers to VLAs, or any such type (these are "variably-modified" types).
Generally, in such cases one returns a pointer to the first element of the array rather than a pointer to the whole array. The pointed-to address is the same either way, but the type is different:
int *foo(size_t row, size_t col);
The return type does not carry information about the length of the pointed-to array, but if C allowed functions to return variably-modified types then that would rely anyway on a mechanism by which the code could know the variable dimensions in any particular context. In other words, if you don't know the expected array length independent of the function's return type, then there's no way you could have used a variably-modified return type anyway.
If indeed you need the function to return both a pointer to a runtime-determined number of elements and also the number of elements, then you can return a struct containing both, or you can return one or both values via pointer parameters.
Update:
It is also possible to declare your function to return a pointer to an array of unspecified size, as @ChronoKitsune suggested. The syntax would be
int (*bar(size_t row, size_t col))[];
, but you will find that return type harder to use in almost every way. For example, it is trickier and uglier to declare variables that can hold the return value:
int (*array_ptr)[] = bar(x, y);
and to access elements of the pointed-to array:
int z = (*array_ptr)[1];
Contrast that with
int *ptr = foo(x, y);
int w = ptr[2];