
C++ does not allow you to change the value of a reference type, effectively treating all references as being const
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 the use of a typedef-name (7.1.3, 14.1) or decltype-specifier (7.1.6.2), in which case the cv-qualifiers are ignored.
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 | ||||
---|---|---|---|---|
| ||||
char &const p;
|
instead of
Code Block | ||||
---|---|---|---|---|
| ||||
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 example, 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 | ||||
---|---|---|---|---|
| ||||
#include <iostream>
void f(char c) {
|
Wiki Markup |
---|
\[[Dewhurst 02|AA. C++ References#Dewhurst 02]\] Gotcha #5, "Misunderstanding References" says: |
Strangely, it's not illegal to apply a
const
orvolatile
qualifier to a type name that is of reference type. Rather than cause an error, the qualifier...can be ignored.
Noncompliant Code Example
Code Block | ||
---|---|---|
| ||
char c = 'c'; char &const p = c; p = 'p'; std::cout << c << std::endl; } |
Implementation Details (MSVC)
On With Microsoft Visual C++Studio 2015, this code compiles without incident and outputs: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
|
G++ version 4.2.4 refuses to compile the code, complaining:
Implementation Details (Clang)
With Clang 3.9, this code produces a fatal diagnostic.
Code Block |
---|
Code Block |
: error: 'const' qualifier qualifiersmay cannotnot be applied to 'char&' |
Compliant Solution
If constant access is required, 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 | ||||
---|---|---|---|---|
| ||||
#include <iostream>
void f(char c) {
const char &p = c;
p = 'p'; // Error: read-only variable is not assignable
std::cout << c << std::endl;
} |
Compliant Solution
This compliant solution removes the const
qualifier.
Code Block | ||||
---|---|---|---|---|
| ||||
#include <iostream>
void f(char c) {
char & | ||||
Code Block | ||||
| ||||
char c = 'c'; char *const 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 |
---|
DCL52-CPP |
Low |
Unlikely |
Low |
P2
L3
P3 | L3 |
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Axivion Bauhaus Suite |
| CertC++-DCL52 | |||||||
Helix QAC |
| C++0014 | |||||||
Klocwork |
| CERT.DCL.REF_TYPE.CONST_OR_VOLATILE | |||||||
Parasoft C/C++test |
| CERT_CPP-DCL52-a | Never qualify a reference type with 'const' or 'volatile' | ||||||
Polyspace Bug Finder |
| CERT C++: DCL52-CPP | Checks for:
Rule fully covered. | ||||||
Clang |
| 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 |
| 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" |
Bibliography
[Dewhurst 2002] | Gotcha #5, "Misunderstanding References" |
[ISO/IEC 14882-2014] | Subclause 8.3.2, "References" |
...
DCL33-CPP. Ensure that restrict-qualified source and destination pointers in function arguments do not reference overlapping objects 02. Declarations and Initialization (DCL) DCL35-CPP. Do not invoke a function using a type that does not match the function definition