Why it does not need to trigger a warning is because of the section of the standard where it occurs - 6.7.6.3p7:
Semantics
[...]
- A declaration of a parameter as ''array of type'' shall be adjusted to ''qualified pointer to type'', where the type qualifiers (if any) are those specified within the [ and ] of the array type derivation. If the keyword static also appears within the [ and ] of the array type derivation, then for each call to the function, the value of the corresponding actual argument shall provide access to the first element of an array with at least as many elements as specified by the size expression.
It appears in the semantics section. A conforming implementation is only required to diagnose those that appear in the constraints. Even when it does not diagnose the violation here, it can use the knowledge of the static
keyword to infer that the argument is not null, and that loop unrolling and other optimizations could expect an array that would have at least that many elements.
Do also note, that the example 5 there says that
void f(double (* restrict a)[5]);
void f(double a[restrict][5]);
void f(double a[restrict 3][5]);
void f(double a[restrict static 3][5]);
are all compatible, i.e. you can mix and match them in function pointer assignments without casts even though one has the static
dimension!
It seems that clang (perhaps rightly so) loses its ability to diagnose anything if the call is realized through a function pointer:
void (*f)(double a[restrict static 3]);
int main(void) {
double a[1] = {0};
f(a);
}
(no diagnostics in Clang 7.0 - remove the *
and you will get them).
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…