Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Patched up example, inc. citation of standard

References are very similar to pointers. A compiler may substitute pointers for references while compiling a program , and references are often considered a safer data structure than pointers. However, C++ imposes several limitations on references. In particular, C++ does not allow you to change which memory a reference points to. Thus, all references are effectively const references.

Inexperienced programmers are therefore tempted to write:

Code Block
bgColor#ffcccc

  char &const p;

instead of:

Code Block
bgColor#ccccff

  char const& p;

If the compiler does not complain of the const reference, the program might be compiled and run and produce surprising results. This is because the first form still allows you to change the character pointed at by p, while the second does not.

Wiki Markup
In fact, \[[ISO/IEC 14882-2003|AA. C++ References#ISO/IEC 14882-2003]\] says, in section 8.3.2 "References":

Cv-qualified references are ill-formed except when the cv-qualifiers are introduced through the use of a typedef (7.1.3) or of a template type argument (14.3), in which case the cv-qualifiers are ignored.

Consequently, some compilers do not flag const references.

Wiki Markup
\[[Dewhurst 02|AA. C++ References#Dewhurst 02]\] Gotcha #5, "Misunderstanding References" says:

...

Noncompliant Code Example

In this code, the character, which happens to point to a string literal, is accessed by a reference. The reference itself is const, but the pointed-to data is not. Consequently it is possible to modify the data via the reference.

Code Block
bgColor#ffcccc
char c = 'c';
char &const p = c;
p = 'p';
cout << c << endl;

Note that in violating this rule, this code also violates STR30-CPP. Do not attempt to modify string literals.

Implementation Details

On Microsoft Visual C++, this code compiles without incident and outputs:

...

Compliant Solution

If constant access reference is required (and the data may be modified via this variable), instead of using a const reference, one can use a const pointer:

Code Block
bgColor#ccccff
char c = 'c';
char *const p = &c;
*p = 'p'; // causes compiler error
cout << c << endl;

Compliant Solution

References are still safer than pointers, so a reference to a const value is the best solution when feasible.

Code Block
bgColor#ccccff

char c = 'c';
const char& p = c;
*p = 'p'; // causes compiler error
cout << c << endl;

Risk Assessment

Const and volatile references may be freely ignored by the compiler, causing unexpected values to be stored and leading to possible data integrity violations.

...

Wiki Markup
\[[Dewhurst 02|AA. C++ References#Dewhurst 02]\] Gotcha #5, "Misunderstanding References"
\[[ISO/IEC 14882-2003|AA. C++ References#ISO/IEC 14882-2003]\]
\[[Cline 09|AA. C++ References#Cline 09]\]\]

...

DCL32-CPP. Do not use names reserved for the implementation      02. Declarations and Initialization (DCL)      DCL34-CPP. Use volatile for data that cannot be cached