const限定指针的限制是多余的?

时间:2016-10-06 21:50:14

标签: c

如果我们将f和g定义为:

void f(const int *restrict a, const int *restrict b, int *c){ ... }
void g(const int *         a, const int *         b, int *c){ ... }
  1. 假设f和g具有相同的主体,从呼叫者的角度来看它们是否相同?
  2. 在被调用者中,我们可以对参数做出相同的假设吗?
  3. 编译器有相同的优化机会吗?
  4. 如果restrict多余,我希望所有三个答案都是肯定的 否则,为什么不呢?

    不要考虑糟糕的编程习惯,例如丢弃const限定符。

3 个答案:

答案 0 :(得分:4)

对于这种情况:

void f(const int *restrict a, const int *restrict b, int *c)

restrict并非多余。这意味着编译器可以假定ac不是别名。例如,如果函数体是:

int d = *a;
*c = 5;
d = *a;

然后编译器可以删除第三行。

C11 6.7.3 / 7涵盖了这一点:

  

此关联在下面的6.7.3.1中定义,要求所有访问   该对象直接或间接使用该特定指针的值。

表示如果通过a访问对象,则不允许通过bc访问该对象。

正式定义见C11 6.7.3.1/4(限制的正式定义):

  

如果 L 用于访问其指定的对象 X 的值,则 X 也会被修改(无论如何) ,则以下要求适用: T 不得为const限定

此处 T a指向的声明类型,即const int L *a,< strong> X 是inta所指向的c

答案 1 :(得分:3)

  

不要考虑糟糕的编程习惯,比如抛弃const限定符。

问题是即使在标准C中,指针上const的存在也不是绑定合同。程序员只是建议被调用者不会尝试修改指针。事实上,只要指针对象最初没有被声明为const对象,就允许代码修改指针对象(在转换之后)。

因此,编译器无法安全地使用const:他们仍然需要检查被调用者的内容,以确保它没有说谎,如果可能的话。

答案 2 :(得分:0)

  

编译器是否有相同的优化机会?

如果我正确理解the standard,那么编译器对具有restrict限定指针的版本有更大的优化机会:

  

在每次执行B [某段代码]时,让L为基于&L [限定限定指针] P的左值。如果L用于访问其指定的对象X的值,并且 X也被修改(无论如何),   然后,以下要求适用: T [类型P指向]不应符合限定条件。 [..]

     

[N1570§6.7.3.1/ 4,强调我的]

从逻辑上讲,如果对象被修改,那么指向它的指针不应该是const限定的。因此,如果指针 const-qualified,则不能修改该对象(无论如何)。

Xmodified Tconst !Tconst Xmodified -> !Tconst
true      true   false   false // oops, must disallow this case
true      false  true    true
false     true   false   true
false     false  true    true

因此,如果编译器看到T const * restrict,那么可以确定在该指针的生命周期内不能修改该指针的“后面”对象。就这样......

  

假设f和g具有等效的主体,从呼叫者的角度来看它们是否相同?

...这比调用者更有力,而不仅仅是使用T const *