关于 C 关键字的一个令人费解的例子 "restrict"
A puzzling example about the C keyword "restrict"
The example 摘自维基百科:
void updatePtrs(size_t *restrict ptrA, size_t *restrict ptrB, size_t *restrict val)
{
*ptrA += *val;
*ptrB += *val;
}
我在main()
中调用这个函数:
int main(void)
{
size_t i = 10;
size_t j = 0;
updatePtrs(&i, &j, &i);
printf("i = %lu\n", i);
printf("j = %lu\n", j);
return 0;
}
根据维基百科的描述,val
指针并没有被加载两次,所以j
的值应该是10,但实际上是20。
我对这个关键字的理解不正确吗?我应该使用 gcc
的一些特定选项吗?
提前致谢。
您的代码导致未定义的行为。 restrict
是您对编译器的承诺,即所有指针参数都指向不同的内存区域。
您将 &i
用于两个参数,这违背了这个承诺。
(事实上,使用 restrict
允许传递重叠指针,但前提是函数内没有通过任何重叠指针进行写入。但通常你不会为 restrict
如果没有写入发生)。
FWIW,在我的 gcc 4.9.2 系统上,输出是 j = 20
在 -O0
和 j = 10
在 -O1
或更高版本,这表明编译器是确实注意到 restrict
。当然,由于它是未定义的行为,您的结果可能会有所不同。
The example 摘自维基百科:
void updatePtrs(size_t *restrict ptrA, size_t *restrict ptrB, size_t *restrict val)
{
*ptrA += *val;
*ptrB += *val;
}
我在main()
中调用这个函数:
int main(void)
{
size_t i = 10;
size_t j = 0;
updatePtrs(&i, &j, &i);
printf("i = %lu\n", i);
printf("j = %lu\n", j);
return 0;
}
根据维基百科的描述,val
指针并没有被加载两次,所以j
的值应该是10,但实际上是20。
我对这个关键字的理解不正确吗?我应该使用 gcc
的一些特定选项吗?
提前致谢。
您的代码导致未定义的行为。 restrict
是您对编译器的承诺,即所有指针参数都指向不同的内存区域。
您将 &i
用于两个参数,这违背了这个承诺。
(事实上,使用 restrict
允许传递重叠指针,但前提是函数内没有通过任何重叠指针进行写入。但通常你不会为 restrict
如果没有写入发生)。
FWIW,在我的 gcc 4.9.2 系统上,输出是 j = 20
在 -O0
和 j = 10
在 -O1
或更高版本,这表明编译器是确实注意到 restrict
。当然,由于它是未定义的行为,您的结果可能会有所不同。