Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Coding style conformance

...

Code Block
bgColor#FFCCCC
langcpp
#include <iostream>

int GlobIglobI;
double GlobDglobD;

struct S {
  int Ii;
  
  S() : Ii(GlobIglobI++) {}
};

struct T : S {
  double Dd;
  
  T() : S(), Dd(GlobDglobD++) {}
};

void f(const S *SomeSessomeSes, std::size_t Countcount) { 
  for (const S *Endend = SomeSessomeSes + Countcount; SomeSessomeSes != Endend; ++SomeSessomeSes) {
    std::cout << SomeSessomeSes->I>i << std::endl;
  }
}

int main() {
  T Testtest[5];
  f(Testtest, 5);
}

This example would still be noncompliant if the for loop had instead been written to use array subscripting, as in the following:

Code Block
for (std::size_t i = 0; i < Countcount; ++i) {
  std::cout << SomeSessomeSes[i].Ii << std::endl;
}

Compliant Solution (Array)

...

Code Block
bgColor#ccccff
langcpp
#include <iostream>

int GlobIglobI;
double GlobDglobD;

struct S {
  int Ii;
  
  S() : Ii(GlobIglobI++) {}
};

struct T : S {
  double Dd;
  
  T() : S(), Dd(GlobDglobD++) {}
};

void f(const S * const *SomeSessomeSes, std::size_t Countcount) { 
  for (const S * const *Endend = SomeSessomeSes + Countcount; SomeSessomeSes != Endend; ++SomeSessomeSes) {
    std::cout << (*SomeSessomeSes)->I>i << std::endl;
  }
}

int main() {
  S *Testtest[] = {new T, new T, new T, new T, new T};
  f(Testtest, 5);
  for (auto Vv : Testtest) {
    delete Vv;
  }
}

The elements in the arrays are no longer polymorphic objects (instead, they are pointers to polymorphic objects), and so there is no undefined behavior with the pointer arithmetic.

...

Code Block
bgColor#ccccff
langcpp
#include <iostream>
#include <vector>

int GlobIglobI;
double GlobDglobD;

struct S {
  int Ii;
  
  S() : Ii(GlobIglobI++) {}
};

struct T : S {
  double Dd;
  
  T() : S(), Dd(GlobDglobD++) {}
};

template <typename Iter>
void f(Iter Ii, Iter Ee) {
  for (; Ii != Ee; ++Ii) {
    std::cout << (*Ii)->I>i << std::endl;
  }
}

int main() {
  std::vector<S *> Testtest{new T, new T, new T, new T, new T};
  f(Testtest.cbegin(), Testtest.cend());
  for (auto Vv : Testtest) {
    delete Vv;
  }
}

Risk Assessment

Using arrays polymorphically can result in memory corruption, which could lead to an attacker being able to execute arbitrary code.

...