c - C99中数组的静态大小

标签 c arrays gcc c99

<分区>

一个非常简单的 C 程序:

#include <stdio.h>
#include <stdlib.h>

void process(int array[static 5]){
    int i;
    for(i=0; i<5; i++)
        printf("%d ", array[i]);
    printf("\n");
}

int main(){

    process((int[]){1,2,3});
    process(NULL);

    return 0;
}

我编译它:gcc -std=c99 -Wall -o demo demo.c

编译,但当我运行它时,它会崩溃(完全可以预见)。

为什么?数组参数中 static 关键字的用途是什么(顺便说一句,这个构造的名称是什么?)?

最佳答案

static 向优化器指示(提示 - 但不超过提示)它可能假设存在最少的适当数量(在示例中为 5 个)元素在数组中(因此数组指针也不为空)。这也是对使用函数的程序员的指示,他们必须将足够大的数组传递给函数以避免未定义的行为。

ISO/IEC 9899:2011

§6.7.6.2 Array declarators

Constraints
¶1 In addition to optional type qualifiers and the keyword static, the [ and ] may delimit an expression or *. If they delimit an expression (which specifies the size of an array), the expression shall have an integer type. If the expression is a constant expression, it shall have a value greater than zero. The element type shall not be an incomplete or function type. The optional type qualifiers and the keyword static shall appear only in a declaration of a function parameter with an array type, and then only in the outermost array type derivation.

§6.7.6.3 Function declarators (including prototypes)

¶7 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.


您的代码会崩溃,因为如果您将空指针传递给需要数组的函数(保证它是包含 5 个元素的数组的开头)。您正在调用未定义的行为,崩溃是处理您的错误的一种非常明智的方式。

当您将一个包含 3 个整数的数组传递给一个保证包含 5 个整数的数组的函数时,情况会更加微妙;同样,您调用未定义的行为并且结果是不可预测的。崩溃的可能性相对较小;虚假结果的可能性很大。

实际上,此上下文中的 static 有两个独立的工作——它定义了两个独立的契约:

  1. 它告诉函数的用户他们必须提供至少包含 5 个元素的数组(如果他们不这样做,他们将调用未定义的行为)。
  2. 它告诉优化器它可能会假定一个指向至少包含 5 个元素的数组的非空指针,并且它可能会相应地进行优化。

如果函数的用户违反了函数的要求,一切都可能会崩溃(“鼻恶魔”等;通常是未定义的行为)。

关于c - C99中数组的静态大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18362315/

相关文章:

c - 观察其他 C 程序正在运行的程序的事件。 [报告击键]

c++ - 为什么#pragma once 不防范多个非 constexpr 定义?

r - 升级到 Mac OS Catalina 后可能无法安装各种 R 软件包

c - 当我将数组传递给函数时值发生变化

c - 用 0 个元素初始化多维 C 数组

c - 在c中隐藏字符串

ruby - 关联数组(或哈希)php 到 ruby

c++ - C++中数组的参数大小

c - 我的增量不起作用 (c)

c - 嵌入式 C - 传递给具有 const 参数的函数的 volatile 和/或变量会导致错误