关于C关键字“限制”的一个令人费解的例子

时间:2016-03-23 10:55:33

标签: 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的一些特定选项吗?

提前致谢。

1 个答案:

答案 0 :(得分:5)

您的代码会导致未定义的行为。 restrict是您对编译器的承诺,即所有指针参数都指向不同的内存区域。

你通过将&i放在两个参数中来打破这个承诺。

(事实上,对于restrict,允许传递重叠指针,但前提是不通过函数中的任何重叠指针进行写操作。但通常你不会打扰restrict如果没有写作的话)。

FWIW,在我的gcc 4.9.2系统上,j = 20的输出为-O0j = 10-O1的输出为restrict,这表明编译器确实在{{1}}的注释。当然,由于它是未定义的行为,您的结果可能会有所不同。