rspec/rules/S6427/cfamily/rule.adoc
Fred Tingaud d3cfe19d7e
Fix broken or dangerous backquotes
Co-authored-by: Marco Borgeaud <89914223+marco-antognini-sonarsource@users.noreply.github.com>
2023-10-30 10:33:56 +01:00

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]