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.
...
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; |
...
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) {
char &const p = c;
p = 'p';
std::cout << c << std::endl;
} |
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 |
|---|
error: 'const' qualifier may not be applied to a reference |
...
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;
} |
...
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <iostream>
void f(char c) {
char &p = c;
p = 'p';
std::cout << c << std::endl;
}
|
Risk Assessment
A const and or volatile reference types 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 | 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 |
|
14
| 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.
Bibliography
| [Dewhurst |
| 2002] | Gotcha #5, "Misunderstanding References" |
| [ISO/IEC 14882-2014] | Subclause 8.3.2, "References" |
...
...