You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C语言中限制数组形参(不转为指针)?

在C语言中为数组形参添加restrict限定符的方法

动机

数组形参可能互为别名,编译器必须考虑这种情况,导致无法进行某些激进优化。比如下面的代码:

int foo(int a[10], int b[10]) {
    a[0] += b[0];
    return a[0] + b[0];
}

int bar(int *a, int *b) {
    a[0] += b[0];
    return a[0] + b[0];
}

int baz(int * __restrict a, int * __restrict b) {
    a[0] += b[0];
    return a[0] + b[0];
}

foo()的编译结果会和bar()类似——编译器必须假设a和b可能指向同一块内存,因此无法把return语句优化成2 * (a[0] + b[0]);而baz()因为用了restrict,编译器可以确定两个指针没有别名,会生成更高效的优化代码。

问题

我希望在函数中使用数组形参(甚至是多维数组,即用一对方括号声明、会退化为指向首元素的一级指针的类型),同时让编译器假设这些形参不存在别名,也就是给数组形参加上restrict限定。在C语言里该怎么实现?如果做不到,原因是什么?

解决方案

在C语言中,你没法直接给数组形式的形参(比如int a[10])加restrict,但可以通过等价的指针声明来实现相同效果:

1. 一维数组场景

普通一维数组形参int a[10]在编译时会自动退化为int *a,直接给指针加上restrict即可:

int foo(int *restrict a, int *restrict b) {
    a[0] += b[0];
    return a[0] + b[0];
}

如果想保留数组长度的提示(仅作为文档,编译器不会强制检查这个长度),可以配合static关键字:

int foo(int *restrict a[static 10], int *restrict b[static 10]) {
    a[0] += b[0];
    return a[0] + b[0];
}

2. 多维数组场景

多维数组形参(比如int a[5][10])会退化为指向一维数组的指针int (*a)[10],给这个指针添加restrict就行:

int multi_foo(int (*restrict a)[10], int (*restrict b)[10]) {
    a[0][0] += b[0][0];
    return a[0][0] + b[0][0];
}

为什么不能直接给数组形参加restrict?

因为C标准规定restrict只能用来限定指针类型,而数组类型本身不属于指针类型。虽然函数中的数组形参会在编译时退化为指针,但数组声明的语法并不支持直接添加restrict限定符,强行编写会被编译器视为语法错误。

内容的提问来源于stack exchange,提问作者einpoklum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 19:14:52