是否常量,正确性给出优化编译器更多的空间? [英] Does const-correctness give the compiler more room for optimization?

查看:98
本文介绍了是否常量,正确性给出优化编译器更多的空间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道,它提高了可读性,使得程序不容易出错,但需要多少提高性能?​​

I know that it improves readability and makes the program less error-prone, but how much does it improve the performance?

和上一个侧面说明,什么是引用和常量指针之间的主要区别?我假设他们存储在内存不同,但怎么回事?

And on a side note, what's the major difference between a reference and a const pointer? I would assume they're stored in the memory differently, but how so?

感谢。

推荐答案

声明一个指针到const或引用的const的帮助从来没有任何编译器优化什么。 (虽然看到这个答案底部的更新。)

Declaring a pointer-to-const or reference-of-const never helps any compiler to optimize anything. (Although see the Update at the bottom of this answer.)

常量声明仅表示如何标识符会内的使用范围的其声明的;它并没有说的基本对象不能改变。

The const declaration only indicates how an identifier will be used within the scope of its declaration; it does not say that the underlying object can not change.

例如:

int foo(const int *p) {
    int x = *p;
    bar(x);
    x = *p;
    return x;
}

编译器不能假设 * P 不被调用修改巴(),因为 p 可能是(例如)一个指向一个全球int和巴()可能会对其进行修改。

The compiler cannot assume that *p is not modified by the call to bar(), because p could be (e.g.) a pointer to a global int and bar() might modify it.

如果编译器知道有足够的了解的调用者富()和酒吧的的内容(),它可以证明巴()不修改 * p ,然后的它也可以执行证明,而无须使用const声明

If the compiler knows enough about the caller of foo() and the contents of bar() that it can prove bar() does not modify *p, then it can also perform that proof without the const declaration.

但是,这是真实的总称。因为常量只,编译器已经可以看到你是如何处理的范围之内的指针或引用的声明范围内的影响;它已经知道你是不是修改基础对象。

But this is true in general. Because const only has an effect within the scope of the declaration, the compiler can already see how you are treating the pointer or reference within that scope; it already knows that you are not modifying the underlying object.

因此​​,在短期,所有的常量确实在这方面是犯错误prevent你。它不会告诉编译器任何它不已经知道了,因此它是不相关的优化。

So in short, all const does in this context is prevent you from making mistakes. It does not tell the compiler anything it does not already know, and therefore it is irrelevant for optimization.

有关调用函数foo的是什么()?这样的:

int x = 37;
foo(&x);
printf("%d\n", x);

编译器可以证明这个打印37,因为富()需要 const int的*

没有。尽管富()需要一个指针到常量,它可能会投的常量性远和修改INT。 (这是的的未定义的行为。)在这里,编译器不能做一般的任何假设;如果它知道有足够的了解富()来做出这样的优化,它会知道,即使没有常量

No. Even though foo() takes a pointer-to-const, it might cast the const-ness away and modify the int. (This is not undefined behavior.) Here again, the compiler cannot make any assumptions in general; and if it knows enough about foo() to make such an optimization, it will know that even without the const.

常量唯一一次可能允许优化的情况下是这样的:

The only time const might allow optimizations is cases like this:

const int x = 37;
foo(&x);
printf("%d\n", x);

下面,修改 X 通过任何(例如,通过采取一个指向它,虚掷了 const的任何机制)是未定义行为。所以编译器是免费的假设你不这样做,它可以不断的37传播进的printf()。这种类型的优化是合法的声明常量的任何对象。 (在实践中,一个局部变量,你永远不要引用没有好处,因为编译器已经可以看到是否在其范围内对其进行修改。)

Here, to modify x through any mechanism whatsoever (e.g., by taking a pointer to it and casting away the const) is to invoke Undefined Behavior. So the compiler is free to assume you do not do that, and it can propagate the constant 37 into the printf(). This sort of optimization is legal for any object you declare const. (In practice, a local variable to which you never take a reference will not benefit, because the compiler can already see whether you modify it within its scope.)

要回答你的旁注的问题,(一)一个const指针指向;和(b)一个const指针可以等于NULL。你是正确的,因为内部重新presentation(即一个地址)是最有可能是一样的。

To answer your "side note" question, (a) a const pointer is a pointer; and (b) a const pointer can equal NULL. You are correct that the internal representation (i.e. an address) is most likely the same.

[更新]

由于克里斯托夫在评论中指出的那样,我的答案是不完整的,因为它没有提到限制

As Christoph points out in the comments, my answer is incomplete because it does not mention restrict.

第6.7.3.1(4)C99标准的说道:

Section 6.7.3.1 (4) of the C99 standard says:

期间的B每次执行时,令L是具有与放大器任何左值;如果L是用来为L基于P.
  访问对象物X,它指定的值,且X也被修改(通过任何方式),
   那么应满足以下要求:T已不得const限定。 ...

During each execution of B, let L be any lvalue that has &L based on P. If L is used to access the value of the object X that it designates, and X is also modified (by any means), then the following requirements apply: T shall not be const-qualified. ...

(这里的B是一个基本块上的P,一个限制指针到T,在范围内。)

(Here B is a basic block over which P, a restrict-pointer-to-T, is in scope.)

所以,如果一个C函数富()声明如下:

So if a C function foo() is declared like this:

foo(const int * restrict p)

...那么编译器的可以的假设没有修改 * P 的生命周期内发生 P - 即)富(在 - 因为否则行为将是不确定的。

...then the compiler may assume that no modifications to *p occur during the lifetime of p -- i.e., during the execution of foo() -- because otherwise the Behavior would be Undefined.

因此​​,在原则上,结合限制的指针给const可以使这两个上面驳回了优化。做任何的编译器真正实现这样的优化,我不知道? (GCC 4.5.2,至少,没有。)

So in principle, combining restrict with a pointer-to-const could enable both of the optimizations that are dismissed above. Do any compilers actually implement such an optimization, I wonder? (GCC 4.5.2, at least, does not.)

注意限制只存在于C,不是C ++(甚至没有的C ++ 0x),除特定的编译器扩展。

Note that restrict only exists in C, not C++ (not even C++0x), except as a compiler-specific extension.

这篇关于是否常量,正确性给出优化编译器更多的空间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆