
Co-authored-by: Marco Borgeaud <89914223+marco-antognini-sonarsource@users.noreply.github.com>
49 lines
1.7 KiB
Plaintext
49 lines
1.7 KiB
Plaintext
== Why is this an issue?
|
|
|
|
The class `std::optional<T>` either stores a value of type `T` or is empty.
|
|
|
|
One way to access the value of a non-empty optional is the ``++operator*++``. But using the dereference operator gives the optional appearance of a pointer when it is not: it models an object. Additionally, attempting to call the ``++operator*++`` on an empty optional will result in undefined behavior.
|
|
|
|
Another way to access the value of a non-empty optional is the function `value()`. But assigning a value to the optional object through this function will throw an exception (`std::bad_optional_access`) if the optional has no value, and the assignment will not happen.
|
|
|
|
For the assignment of an optional to happen correctly, whatever its state, it is better to:
|
|
|
|
* assign the value directly with the `operator=`: e.g. `myOptionalInteger = 3;`
|
|
* use the `emplace` function (for example, when the move or copy operation is expensive or forbidden).
|
|
|
|
== How to fix it
|
|
|
|
The rule raises an issue when the ``++operator*++`` or the `value()` function are used to assign a new value to an optional.
|
|
|
|
=== Code examples
|
|
|
|
==== Noncompliant code example
|
|
|
|
[source,cpp,diff-id=1,diff-type=noncompliant]
|
|
----
|
|
void g(std::optional<int> &val, bool b) {
|
|
if (b) {
|
|
*val = 314; // Noncompliant; the behavior is undefined if the optional is empty.
|
|
} else {
|
|
val.value() = 42; // Noncompliant; it will throw if the optional is empty.
|
|
}
|
|
}
|
|
----
|
|
|
|
==== Compliant solution
|
|
|
|
[source,cpp,diff-id=1,diff-type=compliant]
|
|
----
|
|
void g(std::optional<int> &val, bool b) {
|
|
if (b) {
|
|
val = 314; // Compliant
|
|
} else {
|
|
val = 42; // Compliant
|
|
}
|
|
}
|
|
----
|
|
|
|
== Resources
|
|
|
|
* {cpp} reference - https://en.cppreference.com/w/cpp/utility/optional[std::optional]
|