Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>[Edit: OK so this question is more subtle than I thought at first.]</p> <p>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.)</p> <p>The <code>const</code> declaration only indicates how an identifier will be used within the <em>scope</em> of its declaration; it does not say that the underlying object can not change.</p> <p>Example:</p> <pre><code>int foo(const int *p) { int x = *p; bar(x); x = *p; return x; } </code></pre> <p>The compiler cannot assume that <code>*p</code> is not modified by the call to <code>bar()</code>, because <code>p</code> could be (e.g.) a pointer to a global int and <code>bar()</code> might modify it.</p> <p>If the compiler knows enough about the caller of <code>foo()</code> and the contents of <code>bar()</code> that it can prove <code>bar()</code> does not modify <code>*p</code>, then <em>it can also perform that proof without the const declaration</em>.</p> <p>But this is true in general. Because <code>const</code> 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.</p> <p>So in short, all <code>const</code> 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.</p> <p>What about functions that call <code>foo()</code>? Like:</p> <pre><code>int x = 37; foo(&amp;x); printf("%d\n", x); </code></pre> <p>Can the compiler prove that this prints 37, since <code>foo()</code> takes a <code>const int *</code>?</p> <p>No. Even though <code>foo()</code> takes a pointer-to-const, it might cast the const-ness away and modify the int. (This is <em>not</em> undefined behavior.) Here again, the compiler cannot make any assumptions in general; and if it knows enough about <code>foo()</code> to make such an optimization, it will know that even without the <code>const</code>.</p> <p>The only time <code>const</code> might allow optimizations is cases like this:</p> <pre><code>const int x = 37; foo(&amp;x); printf("%d\n", x); </code></pre> <p>Here, to modify <code>x</code> through any mechanism whatsoever (e.g., by taking a pointer to it and casting away the <code>const</code>) 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 <code>const</code>. (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.)</p> <p>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.</p> <p>[update]</p> <p>As <a href="https://stackoverflow.com/users/48015/christoph">Christoph</a> points out in the comments, my answer is incomplete because it does not mention <code>restrict</code>.</p> <p>Section 6.7.3.1 (4) of the C99 standard says:</p> <blockquote> <p>During each execution of B, let L be any lvalue that has &amp;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. ...</p> </blockquote> <p>(Here B is a basic block over which P, a restrict-pointer-to-T, is in scope.)</p> <p>So if a C function <code>foo()</code> is declared like this:</p> <pre><code>foo(const int * restrict p) </code></pre> <p>...then the compiler <em>may</em> assume that no modifications to <code>*p</code> occur during the lifetime of <code>p</code> -- i.e., during the execution of <code>foo()</code> -- because otherwise the Behavior would be Undefined.</p> <p>So in principle, combining <code>restrict</code> 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.)</p> <p>Note that <code>restrict</code> only exists in C, not C++ (not even C++0x), except as a compiler-specific extension.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload