关于指针指针,C99的"限制"语义是什么?

Mat*_* B. 11 c pointers c99 multidimensional-array restrict-qualifier

我正在做很多矩阵运算,并希望利用C99的restrict指针限定符.

我想设置我的矩阵作为指针的指针,以便轻松下标,如下所示:

int **A = malloc (ncols * sizeof(int *));
A[0] = malloc (nrows * ncols * sizof(int));
for (int i=1; i < ncols; i++) {
    A[i] = A[0] + i*nrows;
}
Run Code Online (Sandbox Code Playgroud)

现在,对于矩阵乘法函数

void mmultiply ( int nrows, int ncols, int **Out, int **A, int **B);
Run Code Online (Sandbox Code Playgroud)

我必须将参数的两个指针限定为受限制吗?这是有效的语法,但我很难确定int *restrict *restrict行为是否有任何不同int **restrict.

那么,指针被正确限制,是通过A[0][col*nrows + row]undefined 访问元素?(即,将编译器假设我通过访问矩阵A[col][row]对的值row,使得row < nrow)?或者我必须保持一致吗?

Dig*_*oss 4

对于第一个问题“是”,如果您使用两个限定符,则意味着不同的东西restrict,具体来说,指针也不会被别名。至于是否有任何区别:理论上是的,实际上,这取决于优化器。

对于第二个问题“是”,它将假设通过行指针访问的任何内容都只能通过行指针访问。

const也可以扔进去。

最后,如果这是位于 -O2、-O3 或 -Os 的 gcc,则编译器已经在基于类型进行别名分析。我确信其他编译器也会这样做。这意味着限制指针与整数已经被理解,只留下可能相互存储的数组。

总之,优化器将假设指针没有被存储为整数,并且它知道它在循环期间没有执行任何指针写入。

因此,您可能会得到相同的代码,但只有一个限制。