rspec/rules/S5981/cfamily/rule.adoc
Fred Tingaud 22b4470f2a
Modify CFamily rules: CPP-4080 Refresh and standardize CppCoreGuidelines references (#3514)
Update all links to C++ Core Guidelines to `e49158a`.

Refresh done using the following script and some manual edits:
db76e34e74/personal/fred-tingaud/rspec/refresh-cppcoreguidelines.py

When re-using this script, be mindful that:
 - it does not cover `shared_content`
 - it does not properly escape inline code in links (e.g., "[=]" or "`mutex`es")
 - it does not change `C++` to `{cpp}` in link titles.

Co-authored-by: Marco Borgeaud <marco.borgeaud@sonarsource.com>
2023-12-20 10:08:18 +01:00

81 lines
2.2 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

== Why is this an issue?
Casting a base-class pointer/reference to a derived-class pointer/reference is commonly referred to as downcasting which can only be done using an explicit cast.
However, the use of ``++static_cast++`` for such a cast is unsafe because it doesn't do any runtime check.  If the cast memory doesn't contain an object of the expected derived type, your program enters the undefined behavior territory.
If your object is polymorphic, you might prefer using ``++dynamic_cast++`` instead, as it allows safe downcasting by performing a run-time check:
* If the cast memory contains an object of the expected derived type, the check succeeds. The result of the ``++dynamic_cast++`` points/refers to the derived object. 
* If the cast memory doesn't contain an object of the expected derived type, the check fails. If the ``++dynamic_cast++`` is used on a pointer, ``++nullptr++`` is returned. If it was used on a reference, ``++std::bad_cast++`` is thrown.
This rule raises an issue when ``++static_cast++`` is used for downcasting.
=== Noncompliant code example
[source,cpp]
----
struct Shape {
virtual ~Shape();
// ...
};
struct Rectangle : public Shape {
double width;
double height;
};
struct Circle : public Shape {
double radius;
};
double computeArea(const Shape* shape) {
const auto* rectangle = static_cast<const Rectangle*>(shape); // Noncompliant
return rectangle->width * rectangle->height;
}
----
=== Compliant solution
[source,cpp]
----
struct Shape {
virtual ~Shape();
// ...
};
struct Rectangle : public Shape {
double width;
double height;
};
struct Circle : public Shape {
int radius;
};
double computeArea(const Shape* shape) {
if(const auto* rectangle = dynamic_cast<const Rectangle*>(shape)) { // Compliant
return rectangle->width * rectangle->height;
}
return 0;
}
----
== Resources
* {cpp} Core Guidelines - https://github.com/isocpp/CppCoreGuidelines/blob/e49158a/CppCoreGuidelines.md#prosafety-type-safety-profile[Type.2: Dont use `static_cast` to downcast]
ifdef::env-github,rspecator-view[]
'''
== Comments And Links
(visible only on this page)
=== relates to: S5823
endif::env-github,rspecator-view[]