Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>References were not present in C. However, C did have what amounts to mutable arguments passed by reference. Example:<br> int foo(int in, int *out) { return (*out)++ + in; }<br> // ...<br> int x = 1; int y = 2;<br> x = foo(x, &amp;y);<br> // x == y == 3.<br> However, it was a common error to forget to dereference "out" in every usage in more complicated foo()s. C++ references allowed a smoother syntax for representing mutable members of the closure. In both languages, this can confound compiler optimizations by having multiple symbols referring to the same storage. (Consider "foo(x,x)". Now it's undefined whether the "++" occurs after only "*out" or also after "in", since there's no sequence point between the two uses and the increment is only required to happen sometime after the value of the left expression is taken.)</p> <p>But additionally, explicit references disambiguate two cases to a C++ compiler. A pointer passed into a C function could be a mutable argument or a pointer to an array (or many other things, but these two adequately illustrate the ambiguity). Contrast "char *x" and "char *y". (... or fail to do so, as expected.) A variable passed by reference into a C++ function is unambiguously a mutable member of the closure. If for instance we had<br> // in class baz's scope<br> private: int bar(int &amp;x, int &amp;y) {return x - y};<br> public : int foo(int &amp;x, int &amp;y) {return x + bar(x,y);}<br> // exit scope and wander on ...<br> int a = 1; int b = 2; baz c;<br> a = c.foo(a,b);<br> We know several things:<br> bar() is only called from foo(). This means bar() can be compiled so that its two arguments are found in foo()'s stack frame instead of it's own. It's called copy elision and it's a great thing.</p> <p>Copy elision gets even more exciting when a function is of the form "T &amp;foo(T &amp;)", the compiler knows a temporary is going in and coming out, and the compiler can infer that the result can be constructed in place of the argument. Then no copying of the temporary in or the result out need be compiled in. foo() can be compiled to get its argument from some enclosing stack frame and write its result directly to some enclosing stack frame.</p> <p>a recent article about copy elision and (surprise) it works even better if you pass <em>by value</em> in modern compilers (and how rvalue references in C++0x will help the compilers skip even more pointless copies), see <a href="http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/" rel="nofollow">http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/</a> .</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