Issues regarding inline-allocated array parameters with "out" and "ref"
Vala code:
void func(out int arr[1]) {
arr[0] = 1;
}
void main() {
int[] arr;
func(out arr);
}
Generated C code:
void
func (gint** arr)
{
gint _vala_arr[1] = {0};
_vala_arr[0] = 1;
if (arr) {
*arr = _vala_arr;
}
}
void
_vala_main (void)
{
gint* arr = NULL;
gint arr_length1 = 0;
gint _arr_size_ = 0;
gint _tmp0_[1] = {0};
func (&_tmp0_);
arr = (g_free (arr), NULL);
arr = _tmp0_;
arr_length1 = -1;
_arr_size_ = arr_length1;
arr = (g_free (arr), NULL);
}
Valac warnings:
test.vala:2.5-2.14: warning: use of possibly unassigned parameter `arr'
arr[0] = 1;
^^^^^^^^^^
test.vala:1.11-1.24: warning: use of possibly unassigned parameter `arr'
void func(out int arr[1]) {
^^^^^^^^^^^^^^
GCC warnings:
test.c: In function ‘_vala_main’:
test.c:26:8: warning: passing argument 1 of ‘func’ from incompatible pointer type [-Wincompatible-pointer-types]
26 | func (&_tmp0_);
| ^~~~~~~
| |
| gint (*)[1] {aka int (*)[1]}
test.c:10:14: note: expected ‘gint **’ {aka ‘int **’} but argument is of type ‘gint (*)[1]’ {aka ‘int (*)[1]’}
10 | func (gint** arr)
| ~~~~~~~^~~
There are a bunch of issues here:
- Valac warnings although the array gets populated.
- The
func
function in C sets*arr
to a stack-allocated array, which leaves scope when the function returns. - The
_vala_main
function callsg_free
on a stack-allocated array.
But after all, does it even make sense to allow having an inline-allocated array parameter as out
?
Similarly, marking an inline-allocated array parameter ref
results in a similar issue. Vala code:
void func(ref int arr[1]) {
arr = new int[1];
arr[0] = 1;
}
void main() {
int arr[1];
func(ref arr);
}
Generated C code:
void
func (gint** arr)
{
(*arr)[0] = 1;
}
void
_vala_main (void)
{
gint arr[1] = {0};
func (&arr);
}
GCC complains and running that program segfaults because &arr
really becomes &arr[0]
.
To me it seems out
/ref
shouldn't make any difference to not having out
/ref
for inline-allocated array parameters, since a reference is passed in both cases anyway, and the array can hence be populated by the callee. An owned inline-allocated array (no ref
) would of course be a different thing, since it's cleared at the function end.