3 ms·
You can pass real references to arrays using C99's variably modified types: int foo(int len, int (*arr)[len]) { printf("number of elements in *arr: %
by caf 8y ago
You can pass real references to arrays using C99's variably modified types:
int foo(int len, int (*arr)[len])
{
printf("number of elements in *arr: %zu\n", sizeof *arr / sizeof (*arr)[0]);
}
int main()
{
int a[6];
int b[10];
foo(6, &a);
foo(10, &b);
return 0;
}
If you do this, the compiler clearly has the information to do at least dynamic bounds checks in 'foo', which it may also be able to statically eliminate (eg if there is a loop from 0 to len - 1).
It might be nice if there was some syntactic sugar for this that made the 'len' parameter implicit and unnamed, and didn't need the explicit & / * on the array pointer.
- a1369209993 8y agoI had sort-of forgotten about those. len needs to be explicit unless it's packaged as eg arr.len. Also (* arr)[i] is just as unacceptable as (* p).item, but you can't do arr[i] unless you abandon the ability to do indexing on raw pointers, which would break essentially all of C.
- caf 8y agoThe length doesn't really need to be explicit because it's available through sizeof, although I guess that having to divide by the element size makes that a little inconvenient. Maybe you could do something like arr->[i] as sugar for (*arr)[i]?
- WalterBright 8y agoThat design is so awkward and clumsy I've never seen it used in production code. Worse, the user has to manually repeat the array length in the function call, a prime defect attracter.
- caf 8y agoNo argument on the awkwardness. The compiler should be able to diagnose incorrect array length passed at the call site, though?
- WalterBright 8y agoThat would require data flow analysis, which is a tricky thing to specify in the Standard, because how far should it go? For example, should it track values through functions like: int length(int len) { return len; } It would also mean no slices.
- a1369209993 8y agoThat's why I like the index type idea: [n] i = ...; int i1 = length(i); /* fine, but we dont know what i1 is */ [n] i2 = length(i); /* error, we assume length can return any int */ [n] i3 = length(i) < n else panic(""); /* also fine, and maybe we can optimize out the check, but we don't have to */