rspec/rules/S5405/cfamily/rule.adoc

66 lines
1.7 KiB
Plaintext
Raw Normal View History

2021-04-28 16:49:39 +02:00
A base class and its derived class often differ in size.
Accessing an array of a derived class through a pointer to the base class leads to wrong pointer arithmetic and can then corrupt memory.
2021-04-28 16:49:39 +02:00
== Noncompliant Code Example
----
struct Base { /*...*/};
struct Derived : public Base { /*...*/};
void f(Base const &b);
int main() {
const size_t size = 4;
Derived derivedArray[size];
Base* basePointer = derivedArray; // Noncompliant
f(basePointer[2]); // The arithmetic will use the size of Base, not the size of Derived, and point to a random byte in the array
}
----
If you need to do a cast from derived to base in an array, do it element by element.
2021-04-28 16:49:39 +02:00
== Compliant Solution
----
#include<iostream>
using namespace std;
struct Base {
int iBase = 0;
};
struct Derived : public Base {
int iDerived = 0;
};
int main() {
const size_t size = 4;
Derived derivedArray[size];
for(int i=0; i<size; ++i) {
derivedArray[i].iBase = i; // store : 0 1 2 3
derivedArray[i].iDerived = i*1000;
}
for(int i=0; i<size; ++i) {
cout<<"derivedArray["<<i<<"].iBase="<<derivedArray[i].iBase<<endl; // display : 0 1 2 3
cout<<"base of derivedArray["<<i<<"].iBase="<<static_cast<Base*>(derivedArray+i)->iBase<<endl; // display : 0 1 2 3
}
return 0;
}
----
2021-04-28 16:49:39 +02:00
== See
* https://github.com/isocpp/CppCoreGuidelines/blob/036324/CppCoreGuidelines.md#c152-never-assign-a-pointer-to-an-array-of-derived-class-objects-to-a-pointer-to-its-base[{cpp} Core Guidelines C.152] - Never assign a pointer to an array of derived class objects to a pointer to its base
ifdef::env-github,rspecator-view[]
'''
== Comments And Links
(visible only on this page)
include::comments-and-links.adoc[]
endif::env-github,rspecator-view[]