CertC++-DCL52¶
Never qualify a reference type with const or volatile
Required inputs: IR
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
char &const p;
instead of
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.
#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.
warning C4227: anachronism used : qualifiers on reference are ignored
When run, the code outputs the following.
p
Implementation Details (Clang)
With Clang3.9, this code produces a fatal diagnostic.
error: 'const' qualifier may not be applied to 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.
#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.
#include <iostream>
void f(char c) {
char &p = c;
p = 'p';
std::cout << c << std::endl;
}
Risk Assessment
A
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 | P3 | L3 |
Bibliography
| [ Dewhurst 2002] | Gotcha #5, "Misunderstanding References" |
| [ ISO/IEC 14882-2014] | Subclause 8.3.2, "References" |
Possible Messages
Key |
Text |
Severity |
Disabled |
|---|---|---|---|
cafe_message |
{} |
None |
False |
Options¶
This rule shares the following common options: exclude_in_macros, exclude_messages_in_system_headers, excludes, extend_exclude_to_macro_invocations, includes, justification_checker, languages, post_processing, provider, report_at, severity
The following places define options that affect this rule: Stylechecks, Analysis-GlobalOptions
message_predicate¶
message_predicate : typing.Callable[[Cafe_Message], bool] | None = None
True for messages to
report.
reported_messages¶
reported_messages : set[int] | None = {512}
reported_severities¶
reported_severities : set[str] = {'error', 'remark', 'warning'}
use_error_number¶
use_error_number : bool = False
use_rule_severity¶
use_rule_severity : bool = True