Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

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 the value of a reference points to. Thus, type, effectively treating all references are effectively as being 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 MarkupIn fact, \[[ISO/IEC 14882-2003|AA. C++ References#ISO/IEC 14882-2003]\] says, in section 8.3.2 "References" qualified. The C++ Standard, [dcl.ref], paragraph 1 [ISO/IEC 14882-2014], states the following:

Cv-qualified references are ill-formed except when the cv-qualifiers are introduced through introduced through the use of a typedef-name (7.1.3) or of a template type argument (14.3, 14.1) or decltype-specifier (7.1.6.2), in which case the cv-qualifiers are 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:

...

Thus, C++ prohibits or ignores the cv-qualification of a reference type. Only a value of non-reference type may be cv-qualified.

When attempting to const-qualify a type as part of a declaration that uses reference type, a programmer may accidentally write

Code Block
bgColor#ffcccc
langcpp
char &const p;

instead of

Code Block
bgColor#ccccff
langcpp
char const &p; // Or: const char &p;

Do not attempt to cv-qualify a reference type because it results in undefined behavior. A conforming compiler is required to issue a diagnostic message. However, if the compiler does not emit a fatal diagnostic, the program may produce surprising results, such as allowing the character referenced by p to be mutated.

Noncompliant Code Example

In this noncompliant 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 referenceexample, a const-qualified reference to a char is formed instead of a reference to a const-qualified char. This results in undefined behavior.

Code Block
bgColor#ffcccc
langcpp
#include <iostream>
 
void f(char c) {
 = 'c';
char &const p = c;
  p = 'p';
  std::cout << c << std::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:

Code Block

p

G++ version 4.2.4 refuses to compile the code, complaining:

}

Implementation Details (MSVC)

With Microsoft Visual Studio 2015, this code compiles successfully with a warning diagnostic.

Code Block
warning C4227: anachronism used : qualifiers on reference are ignored

When run, the code outputs the following.

Code Block
p

Implementation Details (Clang)

With Clang 3.9, this code produces a fatal diagnostic.

Code Block
Code Block

: error: 'const' qualifiersqualifier may cannotnot be applied to 'char&'

Compliant Solution

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

 a reference

Noncompliant Code Example

This noncompliant code example correctly declares p to be a reference to a const-qualified char. The subsequent modification of p makes the program ill-formed.

Code Block
bgColor#ffcccc
langcpp
#include <iostream>
 
void f(char c) {
  const char &p = c;
  
Code Block
bgColor#ccccff

char c = 'c';
char *const p = &c;
*p = 'p'; // causes compiler error
 Error: read-only variable is not assignable
  std::cout << c << std::endl;
}

Compliant Solution

References are still safer than pointers, so a reference to a const value is the best solution when feasibleThis compliant solution removes the const qualifier.

Code Block
bgColor#ccccff
langcpp
#include <iostream>
 
void f(char c) = 'c';
const{
  char & p = c;
*  p = 'p';
 // causes compiler error
 std::cout << c << std::endl;
}

Risk Assessment

Const and volatile references may be freely ignored by the compilerA const or volatile reference type may result in undefined behavior instead of a fatal diagnostic, causing unexpected values to be stored and leading to possible data integrity violations.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

DCL33

DCL52-CPP

low

Low

unlikely

Unlikely

medium

Low

P2

P3

L3

Automated Detection

Tool

Version

Checker

Description

Axivion Bauhaus Suite

Include Page
Axivion Bauhaus Suite_V
Axivion Bauhaus Suite_V

CertC++-DCL52
Helix QAC

Include Page
Helix QAC_V
Helix QAC_V

C++0014
Klocwork
Include Page
Klocwork_V
Klocwork_V
CERT.DCL.REF_TYPE.CONST_OR_VOLATILE
Parasoft C/C++test

Include Page
Parasoft_V
Parasoft_V

CERT_CPP-DCL52-a

Never qualify a reference type with 'const' or 'volatile'

Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C++: DCL52-CPP

Checks for:

  • const-qualified reference types
  • Modification of const-qualified reference types

Rule fully covered.

Clang
Include Page
Clang_V
Clang_V

 Clang checks for violations of this rule and produces an error without the need to specify any special flags or options.
SonarQube C/C++ Plugin
Include Page
SonarQube C/C++ Plugin_V
SonarQube C/C++ Plugin_V
S3708

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

References

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]\]\]

Bibliography

[Dewhurst 2002]Gotcha #5, "Misunderstanding References"
[ISO/IEC 14882-2014]Subclause 8.3.2, "References"


...

Image Added Image Added Image Added 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