关于函数参数中 C99 的数组大小 "guarantee" 特性的实际优势?

On the practical advantage to C99's array size "guarantee" feature in function parameters?

C99 引入了一个新的函数参数表示法,其中 static 关键字可用于指定参数至少有 N 个元素。

6.7.6.3 Function declarators, p7

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.

例如

void func(int x[static 10])
{
    /* something */
}

表示 x 至少有 10 个元素。但这不是约束,因此编译器不需要发出诊断。

上面的 C99 rationale 声明:

[..] It would be a significant advantage on some systems for the translator to initiate, at the beginning of the function, prefetches or loads of the arrays that will be referenced through the parameters. There is no way in C89 for the user to provide information to the translator about how many elements are guaranteed to be available.

In C99, the use of the static keyword in:

void fadd(double a[static 10], const double b[static 10]) {
    int i;
    for (i = 0; i < 10; i++) {
        if (a[i] < 0.0)
            return;
        a[i] += b[i];
    }
    return;
}

guarantees that both the pointers a and b provide access to the first element of an array containing at least ten elements. The static keyword also guarantees that the pointer is not NULL and points to an object of the appropriate effective type.

基本原理似乎表明比 C 标准中规定的保证更强。

基于这些事实:

(显然,更好的编译时诊断可能是一种用途——但这既不是“显着优势”,也无助于按预期进行优化。此外,编译器 如果他们在没有像这样的正式功能的情况下推断出潜在的空指针取消引用,则总是可以发出诊断。

我不完全理解你的问题,但我认为你可能对这里缺少“约束”意味着什么感到困惑。这不是约束,并且编译器没有义务发出诊断,因为编译器不一定能够在调用它的点看到函数的定义。 static 数组大小保证是函数 定义 的 属性,而不是函数 type/声明。这有多种可能的原因,最有可能的是不想声明 with/without 它不兼容的函数类型。

不幸的是,这将功能限制为仅用于优化,而不是正确性检查,除非编译器(或链接器)可以看到不匹配。该功能的“优势”是编译器可以进行优化以读取在抽象机器上不会读取的索引。例如,在:

int foo(int a, int b[static 1])
{
    if (!a) return 0;
    else return a & *b;
}

分支可以优化掉