c++ CRTP stack corruption - c++

when running the following code on MSVC 2013, x64 Debug config, it will show up a message box with this famous error message when quitting the main() function
"Run-Time Check Failure #2 - Stack around the variable 'tmp' was corrupted.".
The question I can't answer is: Why?
note that no error message will occur when running on Release config. (why?)
disclaimer: this is just a sample code, meaning that I'm trying to use this same design on other classes (one base and several derived) with much more methods and template arguments and with a much more complex data type than the basic int*.
#include <iostream>
template <class T>
class base {
public:
base() {
static_cast<T*>(this)->setData();
}
~base() {
static_cast<T*>(this)->destroyData();
}
void print() {
static_cast<T*>(this)->print_int();
}
};
class derived : public base<derived> {
public:
void setData() {
x = new int();
}
void destroyData() {
delete x;
x = nullptr;
}
void print_int() {
std::cout << "x = " << *x << std::endl;
}
private:
derived() {}
derived(const derived& other) {}
inline derived& operator= (derived copy) {}
int *x;
};
int main() {
base<derived> tmp;
tmp.print();
return 0;
}
EDIT:
#Yakk if I understand correctly, you propose as solution this code:
#include <iostream>
template <class T>
class mix_in : public T
{
public:
mix_in() { (this)->setData(); }
~mix_in() { (this)->destroyData(); }
void print() { (this)->print_int(); }
};
class foo
{
public:
void setData()
{
x = new int();
}
void destroyData()
{
delete x;
x = nullptr;
}
void print_int()
{
std::cout << "x = " << *x << std::endl;
}
foo() {}
private:
int *x;
};
int main()
{
mix_in<foo> tmp;
tmp.print();
return 0;
}
It works just fine, thank you. I'll probably use this pattern since it seems that there's no solution to use CRTP for what I'm trying to do.
But I still would like to understand why the stack corruption happens. In spite of all the discussion around use or not use CRTP for all things, I'd like to understand very precisely why it happens.
Thank you again.

As for your code shown in main():
int main() {
base<derived> tmp;
tmp.print();
return 0;
}
base<derived> tmp; that's wrong usage of this pattern, you wanted derived tmp;.
The point of the CRTP is that the derived class is injected to the base class and provides implementations for certain features that are resolved at compile time.
The base class is inherently intended, to be instantiated exclusively via inheritance. Thus you should ensure not to have any instantiations outside an inheritance context.
To avoid users of your implementation trapped by this misconception, make base's constructor(s) protected:
template <class T>
class base {
public:
~base() {
static_cast<T*>(this)->destroyData();
}
// ...
protected:
T* thisPtr;
base() : thisPtr(static_cast<T*>(this)) {
}
};
NOTE: The base class shouldn't call any methods dependent on the fully initialized derived class methods from within your base class constructor though, as you have shown with your sample (static_cast<T*>(this)->setData();)!
You may store the reference to T* for later use though, as shown in the above sample.
class derived : public base<derived> {
public:
derived() {
setData();
}
void destroyData() {
delete x;
x = nullptr;
}
void print_int() {
std::cout << "x = " << *x << std::endl;
}
private: // ????
derived(const derived& other) {}
inline derived& operator= (derived copy) {}
int *x;
};
Also it's a bit unclear, why you want to hide copy constructor and assignment operator for your class?

tmp is a base<derived>, not a derived. The point of CRTP is that the base class "knows" the object's actual type because it's being passed as the template parameter, but if you manually create a base<derived>, then the base class functions would think the object is a derived, but it isn't - it's just a base<derived>. Weird things (undefined behavior) happen as a result. (As noted in the other answer, you are also printing out something without setting it...)
As to your second question, the checks generated by MSVC to detect those sorts of programmer errors appears to be turned off in Release mode, presumably for performance reasons.

template <class T> class mix_in:public T {
public:
base() { (this)->setData(); }
~base() { (this)->destroyData(); }
void print() { (this)->print_int(); }
};
Rename derived to foo. Do not inherit from mix_in or base in foo.
Swap base for mix_in in main.
CRTP is not the solution to all problems.

You say in comments,
the derived class will never be instantiated, its constructor is never called
Others have already pointed out the undefined use of an unconstructed object. To be specific, consider that int *x is a derived member, and your base<derived> usage generates calls, in sequence, to derived::set_data(), derived::print_int(), and on exit derived::destroy_data(), all member functions of an object that doesn't exist, referring to a member for which you've never allocated space1.
But I think what you're after is wholly legitimate. Factoring code is the whole point of templates and inheritance, i.e. to make important code easier to even identify let alone comprehend, and any later refactoring easier to do, by abstracting out boilerplate.
So:
template < class T >
struct preconstruction_access_subset {}; // often left empty
template < class T, class S = preconstruction_access_subset<T> >
struct base : S {
base() { S::setData(); }
~base() { S::destroyData(); }
void print() { S::print_int(); }
};
// ... later ...
#include <iostream>
struct derived;
template<> struct preconstruction_access_subset<derived> {
// everything structors in `base<derived>` need
int *x;
void setData() { x = new int; }
void destroyData() { delete x; }
void print_int() { std::cout << x << '\n'; }
};
struct derived : base<derived> {
// everything no structors in any base class need to access
};
int main() {
base<derived> tmp;
tmp.print();
}
In this example print_int() isn't actually accessed during construction, so you could drop it back into the derived class and access it from `base as for "normal" CRTP, it's just a matter of what's clearest and best for your actual code.
1 That isn't the only problem, just the only one that's apparent without considering any reliance the compiler itself might need to place on the construction sequence. Think independent-name binding and potential inlining and the ways object identity morphs during {de,con}struction and compiler code factoring for all the potential template/inheritance/member-function/etc. combinations. Don't just hoist the int *x; to solve the current symptom, that would just kick the trouble farther down the road even if yours doesn't get that far yet.

Related

How to access inherited class attribute from a third class?

The goal of the code structure below is to be able to store pointers to objects of any class inherited from 'A'.
When I run this code, I get 0 written out, but what I'm trying to access is the 'B' object's 'num' value, which is 1. How can I do that?
As far as I know, when you create an inherited class's object, you create an object of the parent class too automatically. So can I somehow access the parent class object from it's child and set it's class member to match?
See minimal reproducible example below.
Update: Virtual functions solved the problem.
#include <iostream>
class A
{
public:
int num;
A()
{
num = 0;
}
};
class B : public A
{
public:
int num;
B()
{
num = 1;
}
};
class C
{
public:
A* ptr_array[2];
C()
{
ptr_array[0] = new B();
}
void print()
{
std::cout << ptr_array[0]->num << std::endl;
}
};
int main()
{
C* object_c = new C();
object_c->print();
return 0;
}
The problem is that you define a member num in A, and another member num in B. So an object of type B has two members called num, and you're leaving it to the compiler to choose which one to use -- which it does, according to logical rules which may be unfamiliar to you.
If you remove the line in num; from the definition of B, the code will work as you intend.
Your array is a red herring. You are only using one pointer. Might just as well have it as a member for the sake of the example.
I suppose you might need something like this (note, untested code).
#include <memory>
#include <iostream>
class A {
public:
A() : m_num(0) {} // use this instead of assignment in the c'tor body
virtual int getNum() { return m_num; } // this is **the** way to use inheritance
virtual ~A() = default; // required
private:
int m_num;
};
class B : public A {
public:
B() : m_otherNum(1) {}
virtual int getNum() { return m_otherNum; } // does something different from A
private:
int m_otherNum; // you could also call it m_num, but for clarity I use a different name
};
class C {
public:
C() : m_a (std::make_unique<B>()) {} // note, use this instead of new B
void print() {
std::cout << m_a->getNum() << std::endl;
}
private:
std::unique_ptr<A> m_a; // note, use this instead of A* m_a;
};
I have no way of knowing if this is really what you need (or you think you need). This is how inheritance is supposed to be used in object-oriented programming. You can use it in various other ways and produce correct (as far as the language definition is concerned) programs. But if this is the case, then (public) inheritance is likely not the best tool for the job.

Class with replaceable method that is called many times

I want to write a class A with two methods b and c.
The method b calls c.
I want to be able to replace c with anything I like.
I think I can do that if I make c a function pointer or virtual method.
However, b will be called for many times. Will these two solutions affect the performance?
Is it possible to redesign this to avoid using function pointers/virtual methods?
Test inheritance:
#include <iostream>
class A {
public:
A() {}
void b() { c(); }
void c() { std::cout << "1\n"; }
};
class B : public A {
public:
void c() { std::cout << "2\n"; }
};
int main() {
B b;
b.b();
}
Result:
1
Not 2.
Edit: I want to specify what c does at compile time. There are multiple forms of c that I want to plug into the same b method.
Both virtual functions and function pointers suffer from the same performance problems.
First, it is the general inability for compiler to inline those calls. Generally compiler will have to do real function calls and assume side effects, so a lot of optimization techniques can't be performed. Often the impact is quite significant.
Second, during code execution, CPU will generally not be able to prefetch code past the pointer call - since it won't know where the execution will be transferred to. However, hardware call devirtualizers, similar to branch predictors, try to speculatively prefetch instructions based on past performance, and after several calls they are trained and do a good job there. However, lack of inlining still bites you.
If you want no performance penalties, you could use CRTP:
template <typename Derived>
class A {
public:
A() {}
void b() { static_cast<Derived*>(this)->c(); }
void c() { std::cout << "1\n"; }
};
class B : public A<B> {
public:
void c() { std::cout << "2\n"; }
};
int main() {
B b;
b.b();
}
Live example: https://onlinegdb.com/SJzxbtqjz
However, this might not be what you want - it all depends on your use case, which I cannot tell from your question. Make sure you read the pitfalls section on the wikipedia page I linked above:
One issue with static polymorphism is that without using a general
base class like "Shape" from the above example, derived classes cannot
be stored homogeneously as each CRTP base class is a unique type. For
this reason, it is more common to inherit from a shared base class
with a virtual destructor, like the example above.
EDIT:
Otherwise, you'll need to do what you suggested, and pay the price of going through a function pointer. However, if the function you are calling is not something very simple, you probably won't see a difference in performance.
EDIT 2:
The compiler will completely inline the call toc() with appropriate optimizations.
GCC 7.3 with -O2 optimization flag, and a bit simpler code (just to avoid complexity of std::cout):
template <typename Derived>
class A {
public:
A() {}
int b() { return static_cast<Derived*>(this)->c(); }
int c() { return 1; }
};
class B : public A<B> {
public:
int c() { return 2; }
};
int f() {
B b;
return b.b();
}
will generate no code for class B, and generate the following assembly for f:
f():
mov eax, 2
ret
Live example: https://godbolt.org/g/Mh99bZ
Template solution:
#include <iostream>
struct X1 {
static void c() { std::cout << "1\n"; }
};
struct X2 {
static void c() { std::cout << "2\n"; }
};
template <class X>
class A {
public:
A() {}
void b() { X::c(); }
};
int main() {
A<X1> a;
a.b();
A<X2> b;
b.b();
}
Result:
1
2
Solution with reference and template.
It is better than just template because the method c can use the attributes within the class X1.
#include <iostream>
class X1 {
public:
X1(int v) { _v = v; }
void c() {
std::cout << "X1: " << _v << "\n";
}
int _v;
};
template <typename X>
class A {
public:
A(X& x) : _x(x) {}
void b() { _x.c(); }
private:
X& _x;
};
template <typename X>
A<X> make_A(X& x) { return A<X>(x); }
int main() {
X1 x1(10);
// A a1(x1); ///< need c++17
auto a = make_A(x1); ///< works for c++11
a.b();
}
Result:
X1: 10

Override pointer-to-member-function

I have these two classes:
class A {
public:
A() { m_ptr = NULL; }
void (*m_ptr)();
void a() { if (m_ptr) m_ptr(); }
};
class B : public A {
public:
B() { m_ptr = b; }
void b() {
std::cout << "B::b() is called" << std::endl;
}
};
And I want to use them like this:
B b;
b.a();
and get the following to be called B::b().
Of course this is not being compiled as B::b is not of type void(*)().
How can I make it work?
UPDATE. To whom who asks "why?" and "what for?".
The class A is a very basic class which has many successors in production code. The class B is 6-th successor and I want to extend A (the most convinient place) to call there one more method (from B) which can be present and may be not in another successors af A and B.
A virtual method with empty body can be employed for that but it is ugly and I want to avoid it. Abstract method even more so (because of existing derived successors code).
I don't want to use external function of type void (*)() to not loose access to internal data of all hierarchy.
You can't make it work as your classes are defined now.
Calling a non-static member function of another class requires an instance of that class. You either need to store a reference to the object that owns the member function when storing the function pointer, or pass a reference to the object when you make the call to A::a.
You also need to declare m_ptr with the type void (B::*)(), which is pointer to member of B that is a function taking no parameters and returning void.
Look at this example:
class A {
public:
A() { m_ptr = nullptr; }
void a(B& b) { if (m_ptr) (b.*m_ptr)(); } // Now takes reference to B object.
void (B::*m_ptr)(); // Pointer to member function of B.
};
class B : public A {
public:
B() { m_ptr = &B::b; } // Adress of qualified function.
void b() {
std::cout << "B::b() is called" << std::endl;
}
};
Now we can call B::b like this:
B b;
b.a(b); // Pass reference to b when calling.
Your use of inheritence in this way is confusing as it implies that the real problem you are trying to solve is to invoka a member of a derived class through the base class. This is usually accomplished using a simple virtual function like this:
class A {
public:
virtual ~A() {}
void a() const { b(); } // Call b.
private:
virtual void b() const {}
};
class B : public A {
public:
virtual void b() const override { // C++11 override specifier (optional).
std::cout << "B::b() is called" << std::endl;
}
};
And used like this:
B b;
b.a(); // B::b is called.
Well, probably not the purpose of this exercise, but you can simply declare static void b() if you want to make it work.
Another option is to declare friend void b(), but then the "B::b() is called" printout would be stating a wrong fact.
I would suggest using CRTP since you want to avoid virtual mechanism. Note, however, your code might require some design changes to accommodate this pattern. But it does provide type safety and has no run-time overhead. Hope it helps.
Code on ideone.com:
#include <iostream>
#include <type_traits>
namespace so {
class B;
template<typename T>
class A {
public:
template<typename U = T, typename = typename std::enable_if<std::is_same<U, B>::value>::type>
void foo_A() {
std::cout << "foo_A : ";
static_cast<U *>(this)->foo_B();
}
};
class B: public A<B> {
public:
void foo_B() {
std::cout << "foo_B" << std::endl;
}
};
class C: public A<C> {
public:
void foo_C() {
std::cout << "foo_C" << std::endl;
}
};
} // namespace so
int main() {
so::B b_;
so::C c_;
b_.foo_A();
b_.foo_B();
//c_.foo_A(); Compile error: A<C>::foo_A() does not exist!
c_.foo_C();
return (0);
}
Program output:
foo_A : foo_B
foo_B
foo_C

Calling proper derived class' method using templates without using virtual?

I have something like the attached. I basically have a Doer class in which I want to call Func() from it's member without using virtual or with the least code duplication possible. Also, boost is not an option either. I know the example may not be so clear but I hope you get the idea. B
class Base { // a bunch of shared base functionality. Cannot be instantiated by itself }
class D1 : public Base
{
void Func();
}
class D2 : public Base
{
void Func();
}
//----
class Doer
{
Doer(Base* b) : base(b) { }
void DoIt()
{
base->Func();
}
Base* base;
}
Well, you can make Doer templated:
template<class T>
class Doer
{
public:
Doer(T* b) : base(b) { }
void DoIt()
{
base->Func();
}
private:
T* base;
};
But for this I would just add a virtual void Func() to Base instead.
Note that you'll probably want to make Func public in either case :-)
What about this approach:
class Base { // a bunch of shared base functionality. Cannot be instantiated by itself
~Base() { //stuff }
void Func();
}
class D1 : public Base
{
void Func();
}
class D2 : public Base
{
void Func();
}
//----
class Doer
{
Doer(Base* b) : base(b) { }
void DoIt()
{
base->Func();
}
Base* base;
}
Since Func() isn't virtual and is being overloaded by the children, there shouldn't be a vtable or any incurred performance penalty right?
Also, the destructor needs to be called on the base class, but declaring it virtual will impose a vtable?
Can anyone clarify?
Thanks
You can use mixins! They're good for optimization (lots of inlining opportunities and no virtual method calls), but sometimes a little hard to reason about. Here's your example implemented with mixins:
template<class Base> class Doer : Base {
public:
Doer() {}
void DoIt() {
this->Func();
}
};
class D1 {
public:
void Func() {
cout<<"Hello from D1"<<endl;
}
};
class D2 {
public:
void Func() {
cout<<"Hello from D2"<<endl;
}
};
Using this is a little different, since the Doer is same as your Base class instance. The following program:
Doer<D1> *d1 = new Doer<D1>();
Doer<D2> *d2 = new Doer<D2>();
d1->DoIt();
d2->DoIt();
Produces the output:
Hello from D1
Hello from D2
This has the obvious drawback that D1 and D2 aren't forced to implement the "Func" method. If you forget it, you'll get an oh-so-handy C++ template instantiation error instead of "method not found." Clang is a great choice if you're going to be using templates frequently, since you get much more helpful compiler errors than with g++. Another drawback is with constructors: Doer defines the default constructor, but doesn't expose D1's constructor. C++11 allows for constructor inheritance, so this issue can be avoided with a compiler flag.
in fact you don't need to parameterize the whole Doer class. This will work just fine (close to what ccurtsinger was suggesting):
class Base {
public:
void Func() {};
};
class B1 {
public:
void Func() { cout << "in B1::Func" << endl;}
};
class B2 {
public:
void Func() { cout << "in B2::Func" << endl;}
};
class Doer {
public:
template <class B> void Do(B *pb) {pb->Func();}
};
int main() {
B1 b1;
B2 b2;
Doer d;
d.Do<B1>(&b1);
d.Do<B2>(&b2);
return 0;
}
But really there's a bigger question: from the code you said you finally used it seems like at compile time you know exactly which derived classes objects you're dealing with, so code like:
for(auto i = begin(B1_container); i != end(B1_container); ++i) {
i->Func();
}
for(auto j = begin(B2_container); j != end(B2_container); ++j) {
j->Func();
}
should do the trick.
What I'm saying is - you either know in advance that you're working with B1-s here and B2-s there and there's no additional cost for Func() invocation, OR you don't know which one you are to deal with next and then you need to check it's dynamic type of some type of trait or whatever and that's an 'if' and thus branching and thus mispredictions and overhead. Notice, I'm not adding the cost of a function call, which is there in both cases regardless.

C++ Seg fault on reference to stored base class pointer

I'm getting some nasty segmentation faults through the g++ compiler on the following code. Any ideas on why this would happen and how to fix it would be great.
#include <iostream>
using namespace std;
class Base {
public:
Base() {}
virtual ~Base() {};
virtual int getNum(int) = 0;
};
class Derived: public Base {
public:
Derived() :
Base() {}
~Derived() {}
int getNum(int num) {
return num;
}
};
class Foo {
public:
Foo() {
};
void init() {
Derived n;
*baseId = n;
}
void otherStuff() {
cout << "The num is" << baseId->getNum(14) << baseId->getNum(15) << baseId->getNum(16) << baseId->getNum(15) << endl;
}
Derived* baseId;
};
int main() {
Foo f;
f.init();
f.otherStuff();
return 0;
}
Here:
void init() {
Derived n;
*baseId = n;
}
the pointer baseId is never initialised, resulting in undefined behaviour when you dereference it. It might be a good idea to explain what you are trying to do here. If you want to maintain a pointer to a Derived or a Base but which starts off pointing to a derived, you can say:
void init() {
baseId = new Derived;
}
but you will then probably need a copy constructor, an assignment operator and a destructor to manage the pointer.
Also, for several reasons, writing an init() function is not normally a good idea - you are better off doing the work directly in the constructor or its initialisation list.
When you call f.init(), the baseId member of Foo is not initialised, yet you dereference it in init(). Are you sure you don't want something more along the lines of:
baseId = new Derived()
void init() {
Derived n;
*baseId = n;
}
Apart from what Neil noted, derived n is local to your init function. It "dies" when you exit the function, so even if you assigned it correctly, it won't work.
What you want is not assigning on the stack but on the heap:
void init() {
baseId = new Derived();
}
or even better:
void init() {
delete baseId;
baseId = new Derived();
}
and a destructor and constructor pair to prevent problems :
Foo() : baseId(0) {};
~Foo() { delete baseId; }
If going for this method, be sure to either block copy constructor and assignment operator, or implement them properly. To implement them however, you'd need to implement copying of Derived too -- or best: use a safe shared_ptr to store the pointer.