0

C99 allows array parameter sizes to be static:

#include <stdio.h>

int sum(const int v[static 10])
{
    int s = 0;
    for (int i = 0; i < 10; i++)
        s += v[i];
    return s;
}

int main(void)
{
   int v[4] = { 1, 2, 3, 4 };
   printf("%d", sum(v));
}

From what I understand, the compiler should throw an error when calling sum(), because I need to pass an array of at least 10 elements. The compiler, however, seems to ignore the static keyword and proceeds with passing an array of 4 elements. Of course, since the function uses 10 elements, it is undefined behavior (and the output is some random non-sense made of what is beyond the array). What is the problem?

DarkAtom
  • 2,589
  • 1
  • 11
  • 27
  • Is it still ignoring when you pass an 11 member array ? – nikoss May 19 '20 at 11:13
  • Well, when I give your code to `clang-cl` (in Visual Studio 2019), it tells me: **warning : array argument is too small; contains 4 elements, callee requires at least 10 [-Warray-bounds]**. Have you enabled (all) warnings for your compiler? And what compiler are you using? – Adrian Mole May 19 '20 at 11:15
  • @nikoss The code doesn't give any warning or errors no matter the size. But an 11 element array is fine anyway: it **shouldn't** throw errors. – DarkAtom May 19 '20 at 11:15
  • @AdrianMole I am using GCC 9.2 with `-pedantic-errors` and `-stc=c17` – DarkAtom May 19 '20 at 11:16
  • Have you tried adding `-Wall` or `-Warray-bounds`? – Adrian Mole May 19 '20 at 11:17
  • I tried now, still warning nor error. – DarkAtom May 19 '20 at 11:19
  • 1
    Seems like GCC is catching up with (or overtaking) MSVC in its bugginess! – Adrian Mole May 19 '20 at 11:20
  • 1
    @AdrianMole It's not a bug in gcc. It's not a constraint violation and as such, there's no requirement to issue a diagnostic. It might be [useful to warn these, nevertheless](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50584). And `-Waray-bounds=2` does help in some cases. – P.P May 19 '20 at 11:26
  • @P.P OK, perhaps I was being a bit too harsh! – Adrian Mole May 19 '20 at 11:48
  • @P.P So if it's not a constraint violation, what is the difference between adding and not adding `static`? – DarkAtom May 19 '20 at 12:15
  • Supposedly you aren't allowed to pass a null pointer to a function with a static size array. I believe clang warns if you do. But I don't think many compilers implement this feature even to this day, so it turned out a bit of a fiasco. – Lundin May 19 '20 at 12:42
  • If you want actual bounds-checking type safety, you could however do the trick with `int sum(int(*v)[10])`. And now the caller must do `sum(&v)` with a `v` that's an array of 10 elements. Unfortunately it also means that you lose const correctness. – Lundin May 19 '20 at 12:44
  • @Lundin `const` as a parameter qualifier is just a reminder for the programmer that the function doesn't modify the contents. You can always cast it away if you are evil :( – DarkAtom May 19 '20 at 13:26
  • @DarkAtom Not in case you use array pointers, because then the const ends up with the pointed-at data. See this: https://stackoverflow.com/questions/36199473/const-correctness-for-array-pointers – Lundin May 19 '20 at 13:28
  • @Lundin I never argued that `const` doesn't work well with pointers to arrays. Just said that `const` in general is a gimmick used for compiler diagnostics and nothing more. – DarkAtom May 19 '20 at 13:33
  • @DarkAtom Err, no. Pointer compatibility issues aside, `const` in the context of embedded systems often means "allocate this variable in read-only flash, not in volatile RAM". And the results will be _very_ different, most notably flash variables are preserved after power loss, RAM variables are not. – Lundin May 19 '20 at 13:39
  • I am pretty sure I mentioned *"`const` as a parameter qualifier"*. But let's not pollute this comment section with off-topic stuff. – DarkAtom May 19 '20 at 13:41

0 Answers0