While playing around with polymorphism and templates i eventually dug up a strange (at least for me) behaviour of the scope operator. When i tried to access a method of a *b*aseclass using the *i*nterface with the scope operator within a *d*erived class, i get a linker error. I can only assume that the scope operator doesnt look into the vtable and tries to run the method directly from the interface, which is actually pure virtual.
Here is the example for that:
struct i
{
virtual void set(char* in, short len) = 0;
virtual char* getStr() = 0;
virtual ~i() {}
};
template <int size = 10>
struct b : public i // this one is like an char-Array
{
char str[size];
void set(char* in, short len) { memcpy(this->getStr(),in,len); }
char* getStr() { return str;}
};
template <int size = 10>
struct d : public b<size> // this one is like an cString
{
void set(char* in) { strcpy(this->getStr(),in); }
};
struct final : public d<4>
{
void test()
{
set("abc"); ///< Works
d<4>::set("abc"); ///< Works
//set("abc",3); ///< Error : no matching function for call to 'final::set(const char [4], int)' (its shadowed by d)
//note: candidates are: void d<size>::set(char*) [with int size = 4]
b<4>::set("abc",3); ///< Works
//i::set("abc",3); ///< Linker Error: (.gnu.linkonce.t._ZN5final4testEv+0x68) : Error : undefined reference to `i::set(char*, short)'
//this->set("abc",3); ///< Error : no matching function for call to 'final::set(const char [4], int)' (its shadowed by d too)
((i*) this)->set("abc",3); ///< Works!
}
};
int main()
{
final f;
f.test();
return 0;
}
The background why i tried this, is to avoid changing the template parameter of every call to a templated base class, when i might change the size of the final class.
So can somebody explain me why this happens with the scope operator?
Funny is that it does work, when casting the "this" pointer to a interface pointer and then using the baseclass's method with that. Is this actually valid and practicable?
BTW: i use GCC 4.1.2
EDIT:
Just to clarify, i know d::set is shadowing b::set .. thats not the problem, i am just asking about the linker error!
When you write Base::symbol in a class context, symbol will
always be resolved statically, with name lookup starting in the
class Base. The reason is simple: that's the way you access
masked members in derived classes. Otherwise, you'd be unable
to chain functions, e.g.:
void
Derived::function()
{
Base::function(); // calls the function in Base before doing anything else.
// ...
}
At the time C++ was being developed, this was felt to be
important, and even today, you'd want to support some way of
doing it.
One idea for working around this:
template <int size=10>
struct d : public b<size>
{
typedef b<size> Base;
// ...
};
Then in final, refer to Base::set.
Oh i finally found the answer to my question by myself:
Polymorphism needs a indirection!
As stated here: Polymorphic objects on the stack?
Thanks for pointing THAT out ;)
Related
What's wrong with this:
struct FileListItem {
string sOriginalFn;
time_t ttTimeTaken;
FileListItem(){}
FileListItem(string _sOriginalFn, time_t _ttTimeTaken) :
sOriginalFn (_sOriginalFn), ttTimeTaken (_ttTimeTaken) { }
};
struct FileList : vector<FileListItem> {
int iCurItm;
FileList() : vector(), iCurItm(-1) {};
void Add(string _sOriginalFn, time_t _ttTimeTaken) {
push_back(FileListItem(_sOriginalFn, _ttTimeTaken));
}
}
I get a run-time "read access violation" the first time Add is called.
I then try:
struct FileList : vector<FileListItem> {
int iCurItm;
FileList() : vector(), iCurItm(-1) {};
FileListItem Itm; // <--- new member
void Add(string _sOriginalFn, time_t _ttTimeTaken) {
Itm(_sOriginalFn, _ttTimeTaken); // <--- E0980 pointing to "Itm"
push_back(Itm);
}
}
and get a compile time error:
E0980 - call of an object of a class type without appropriate operator() or conversion functions to pointer-to-function type.
I must have forgotten or missed something since I stopped programming 30 years ago, when Borland C++ was IT...
In the line
Itm(_sOriginalFn, _ttTimeTaken);
You are not calling the constructor for your object. Instead, the compiler interprets this as a function call on the functor Itm. Therefore, it tries to find a valid operator() for the given arguments, to no-avail.
Do not use constructor member initializer list syntax elsewhere than... Constructor member initializer list. Instead, what you have to do here is to assign a new object to your member.
Then, you don't want, ever to inherit from std containers. Their destructor is not virtual so you are exposing yourself to a realm of suffering...
Use composition or type aliasing instead:
struct FileList {
std::vector<FileListItem> flist;
int curItem;
FileList() : flist(), curItem(-1) {}
void Add(string const& _sOriginalFn, time_t _ttTimeTaken) {
// No need to construct the object before, let vector handle it
flist.emplace_back(_sOriginalFn, _ttTimeTaken);
};
As for the read access violation, from the code I see, nothing explains it. Could it be some access related to curItem somewhere in your code that isn't displayed here?
I'm looking into the LLVM source code and I never encountered the following syntax:
class BasicBlock {
public:
typedef iplist<Instruction> InstListType;
private:
InstListType InstList;
static iplist<Instruction> BasicBlock::*getSublistAccess(Instruction*) {
return &BasicBlock::InstList;
}
}
what does the above define? At first it seemed a normal static function but I don't understand the BasicBlock::* part. Seems like a static function which returns a member function pointer and that directly executes that member function's code.
The return type of static member function getSublistAccess is
iplist<Instruction> BasicBlock::*
that is, a pointer to a non-static data member of class BasicBlock, where the data type is iplist<Instruction>.
What getSublistAccess actually returns is &BasicBlock::InstList, that is exactly a non-static data member of class BasicBlock, where the data type is InstListType. i.e., iplist<Instruction>.
Is a function pointer.
You can read this article for detail.
Thanks to iavr for the answer. I'm awarding the answer to him but I'd like to add some details here which will hopefully help someone reading this post.
What I asked and as iavr explained to me, might be understood with the following code:
#include <iostream>
using namespace std;
struct customType {
int b;
};
struct Instruction {};
class BasicBlock {
public:
BasicBlock(int a) { InstList.b = a; }
customType InstList;
static customType BasicBlock::*getSublistAccess(Instruction*) {
return &BasicBlock::InstList;
}
};
int main() {
BasicBlock bb(90);
Instruction justForSignature;
// Get a pointer to a member of type customType through the static function
customType BasicBlock::* ptrToMember = BasicBlock::getSublistAccess(&justForSignature);
cout << (bb.*ptrToMember).b; // Parenthesis are necessary, '.' has higher precedence on *
// Output: 90
return 0;
}
Try it out: http://ideone.com/hYgfh8
I recently created my own scripting language. My code structures are heavily based on polymorphism. (I'm not really sure about how is this called. I've got a virtual function and then I derive the class and let the OS decide what to call on runtime):
class Statement
{
virtual void exec() = 0;
};
class PrintStmt : public Statement
{
void exec()
{
std::cout << expression->eval();
};
class AssignStmt : public Statement
{
void exec()
{
vm->bind_var(name, expression->eval())
};
Any ideas how I can rework this so it can be compiled by a pure C compiler?
I know this is general question and there is no single answer, but how would you do this?
Note: I already downloaded the python code as a reference, but it will take time until I figure out how it is working.
Statement would be a struct. In addition to its data members, you will need a function pointer e.g.
struct Statement
{
void(*exec)(Statement* this); // Function pointer
// Other members
};
You would then have different implementations of the functions per statement type and a function for manufacturing objects of the right type e.g.
static void printExec(struct Statement* this)
{
printf("%s", this->whatever);
}
struct Statement* createPrintStatement()
{
struct Statement* statement = calloc(1, sizeof(struct Statement));
statement->exec = printExec;
return statement;
}
And you would invoke it like this:
statement->exec(statement);
The this pointer gives you access to the data members of the particular struct i.e. the instance whose exec method you invoked.
If you have lots of functions, consider using a vtable.
struct VTable
{
void(*exec)(Statement* this); // Function pointer
const char* (*stringValue)(Statement* this); // Function pointer
};
struct Statement
{
struct VTable* vtable;
// Other members
};
You build each a vtable for each kind of object only once
struct VTable printVTable =
{
printExec,
printStringValue
};
You create new objects thus:
struct Statement* createPrintStatement()
{
struct Statement* statement = calloc(1, sizeof(struct Statement));
statement->vtable = &printVTable;
return statement;
}
and invoke the methods thus
statement->vtable->exec(statement);
The vtable method is more or less what C++ does behind the scenes.
The most straightforward way to convert this to C would probably be to use function pointers.
As #DrewNorman said, you will need to understand how vtables work, class layouts etc, and reimplement it (at least partially) in C. The example code below is very limited but gives you a hint of what to expect.
struct Statement {
void (*exec)(struct Statement* s);
};
struct PrintStmt {
struct Statement statement;
char* what;
};
void print_function(struct Statement* s) {
struct PrintStmt* p = (struct PrintStmt*)s;
printf(p->what);
}
// ...
struct PrintStmt p;
p.statement.exec = &print_function;
p.what = "Hello world";
p.statement.exec(p);
There are numerous C projects that use this kind of technique, GObject comes to my mind but it's far from the only one.
(Note: I'm used to C++ not really to C so this may not even be valid C but you get the idea anyway)
I'm trying to get function addresses which are hidden behind structures. Unfortunately, the void* basic C++ conversion doesn't work, so I used C++ template instead.
1. Basic void* C++ conversion doesn't work with functions inside structures, why?
void * lpfunction;
lpfunction = scanf; //OK
lpfunction = MessageBoxA; //OK
I made a simple structure :
struct FOO{
void PRINT(void){printf("bla bla bla");}
void SETA(int){} //nothing you can see
void SETB(int){} //nothing you can see
int GETA(void){} //nothing you can see
int GETB(void){} //nothing you can see
};
///////////////////////////////////////////
void *lpFunction = FOO::PRINT;
And the compiling error :
error C2440: 'initializing' :
cannot convert from 'void (__thiscall FOO::*)(void)' to 'void *'
2. Is getting function member addresses impossible?
Then, I made a template function which is able to convert a function member to address. Then I will call it by assembly. It should be something like this:
template <class F,void (F::*Function)()>
void * GetFunctionAddress() {
union ADDRESS
{
void (F::*func)();
void * lpdata;
}address_data;
address_data.func = Function;
return address_data.lpdata; //Address found!!!
}
And here is the code :
int main()
{
void * address = GetFunctionAddress<FOO,&FOO::PRINT>();
FOO number;
number.PRINT(); //Template call
void * lpdata = &number;
__asm mov ecx, lpdata //Attach "number" structure address
__asm call address //Call FOO::PRINT with assembly using __thiscall
printf("Done.\n");
system("pause");
return 0;
}
But, I see it is extremely specific. It looks like LOCK - KEY, and I have to make a new template for every set of argument types.
Original (OK) :
void PRINT(); //void FOO::PRINT();
Modify a bit :
void PRINT(int); //void FOO::PRINT(int);
Immediately with old template code the compiler shows :
//void (F::*func)();
//address_data.func = Function;
error C2440: '=' : cannot convert from
'void (__thiscall FOO::*)(int)' to 'void (__thiscall FOO::*)(void)'
Why? They are only addresses.
69: address_data.func = Function;
00420328 mov dword ptr [ebp-4],offset #ILT+2940(FOO::PRINT) (00401b81)
...
EDIT3 : I know the better solution :
void(NUMBER::*address_PRINT)(void) = FOO::PRINT;
int(NUMBER::*address_GETA)(void) = FOO::GETA;
int(NUMBER::*address_GETB)(void) = FOO::GETB;
void(NUMBER::*address_SETA)(int) = FOO::SETA;
void(NUMBER::*address_SETA)(int) = FOO::SETB;
It's much better than template. And by the way I want to achieve the goal :
<special_definition> lpfunction;
lpfunction = FOO::PRINT; //OK
lpfunction = FOO::GETA; //OK
lpfunction = FOO::GETB; //OK
lpfunction = FOO::SETA; //OK
lpfunction = FOO::SETB; //OK
Is this possible?
Pointers to member functions are nothing like pointers to global functions or static member functions. There are many reasons for this, but I'm not sure how much you know about how C++ works, and so I'm not sure what reasons will make sense.
I do know that what you are trying in assembly simply won't work in the general case. It seems like you have a fundamental misunderstanding about the purpose of member functions and function pointers.
The thing is, you are doing some things that you would generally not do in C++. You don't generally build up tables of function pointers in C++ because the things you would use that sort of thing for are what virtual functions are for.
If you are determined to use this approach, I would suggest you not use C++ at all, and only use C.
To prove these pointer types are completely incompatible, here is a program for you:
#include <cstdio>
struct Foo {
int a;
int b;
int addThem() { return a + b; }
};
struct Bar {
int c;
int d;
int addThemAll() { return c + d; }
};
struct Qux : public Foo, public Bar {
int e;
int addAllTheThings() { return Foo::addThem() + Bar::addThemAll() + e; }
};
int addThemGlobal(Foo *foo)
{
return foo->a + foo->b;
}
int main()
{
int (Qux::*func)();
func = &Bar::addThemAll;
printf("sizeof(Foo::addThem) == %u\n", sizeof(&Foo::addThem));
printf("sizeof(Bar::addThemAll) == %u\n", sizeof(&Bar::addThemAll));
printf("sizeof(Qux::addAllTheThings) == %u\n", sizeof(&Qux::addAllTheThings));
printf("sizeof(func) == %u\n", sizeof(func));
printf("sizeof(addThemGlobal) == %u\n", sizeof(&addThemGlobal));
printf("sizeof(void *) == %u\n", sizeof(void *));
return 0;
}
On my system this program yields these results:
$ /tmp/a.out
sizeof(Foo::addThem) == 16
sizeof(Bar::addThemAll) == 16
sizeof(Qux::addAllTheThings) == 16
sizeof(func) == 16
sizeof(addThemGlobal) == 8
sizeof(void *) == 8
Notice how the member function pointer is 16 bytes long. It won't fit into a void *. It isn't a pointer in the normal sense. Your code and union work purely by accident.
The reason for this is that a member function pointer often needs extra data stored in it related to fixing up the object pointer it's passed in order to be correct for the function that's called. In my example, when called Bar::addThemAll on a Qux object (which is perfectly valid because of inheritance) the pointer to the Qux object needs to be adjusted to point at the Bar sub-object before the function is called. So Qux::*s to member functions must have this adjustment encoded in them. After all, saying func = &Qux::addAllTheThings is perfectly valid, and if that function were called no pointer adjustment would be necessary. So the pointer adjustment is a part of the function pointer's value.
And that's just an example. Compilers are permitted to implement member function pointers in any way they see fit (within certain constraints). Many compilers (like the GNU C++ compiler on a 64-bit platform like I was using) will implement them in a way that do not permit any member function pointer to be treated as at all equivalent to normal function pointers.
There are ways to deal with this. The swiss-army knife of dealing with member function pointers is the ::std::function template in C++11 or C++ TR1.
An example:
#include <functional>
// .... inside main
::std::function<int(Qux *)> funcob = func;
funcob can point at absolutely anything that can be called like a function and needs a Qux *. Member functions, global functions, static member functions, functors... funcob can point at it.
That example only works on a C++11 compiler though. But if your compiler is reasonably recent, but still not a C++11 compiler, this may work instead:
#include <tr1/functional>
// .... inside main
::std::tr1::function<int(Qux *)> funcob = func;
If worse comes to worse, you can use the Boost libraries, which is where this whole concept came from.
But I would rethink your design. I suspect that you will get a lot more milage out of having a well thought out inheritance hierarchy and using virtual functions than you will out of whatever it is you're doing now. With an interpreter I would have a top level abstract 'expression' class that is an abstract class for anything that can be evaluated. I would give it a virtual evaluate method. Then you can derive classes for different syntax elements like an addition expression a variable or a constant. Each of them will overload the evaluate method for their specific case. Then you can build up expression trees.
Not knowing details though, that's just a vague suggestion about your design.
Here is a clean solution. By means of a template wrap your member function into a static member function. Then you can convert it to whatever pointer you want:
template<class F, void (F::*funct)()>
struct Helper: public T {
static void static_f(F *obj) {
((*obj).*funct)();
};
};
struct T {
void f() {
}
};
int main() {
void (*ptr)(T*);
ptr = &(Helper<T,&T::f>::static_f);
}
It seems that you need to convert a pointer to a member function to a void *. I presume you want to give that pointer as a "user data" to some library function and then you will get back your pointer and want to use it on some given object.
If this is the case a reinterpret_cast<void *>(...) could be the right thing... I assume that the library receiving the pointer is not using it.
I've been making a game which uses the Box2D physics engine, and I've come across some weirdness with the stack pointer (ESP) and multiple inheritance. I've managed to reproduce it in a minimal amount of code, and it seems that the order in which I declare the classes to be used in multiple inheritance seems to dictate whether the program crashes or not.
#include <iostream>
#include <string.h>
using namespace std;
class IPhysicsObject
{
public:
virtual void Collide(IPhysicsObject *other, float angle, int pos)=0;
};
class IBoardFeature
{
public:
IBoardFeature(){};
~IBoardFeature(){};
virtual bool OnAttach(int x){ return true; }
virtual bool Update(int x, float dt)=0;
};
/*
class CScorezone : public IBoardFeature, public IPhysicsObject // this breaks !!!
class CScorezone : public IPhysicsObject, public IBoardFeature // this works !!!
*/
class CScorezone : public IBoardFeature, public IPhysicsObject
{
public:
CScorezone(){}
~CScorezone(void){}
virtual bool Update(int x, float dt)
{
return true;
}
virtual void Collide(IPhysicsObject *other, float angle, int pos)
{
}
virtual bool OnAttach(int x){ return true; }
};
int main(int argc, char *argv[])
{
CScorezone *scoreZone = new CScorezone();
CScorezone *otherZone = new CScorezone();
void *voidZone = scoreZone;
IPhysicsObject *physZone = static_cast<IPhysicsObject*>(voidZone);
physZone->Collide(otherZone, 10, 1);
delete scoreZone;
delete otherZone;
// wait for user input
int x;
cin >> x;
return 0;
}
Running this in debug mode causes the following error
Run-Time Check Failure #0 - The value
of ESP was not properly saved across a
function call. This is usually a
result of calling a function declared
with one calling convention with a
function pointer declared with a
different calling convention.
When I step in to the following line of code:
physZone->Collide(otherZone, 10, 1);
I notice it's going into CScoreZone::OnAttach, not CScoreZone::Collide. Why is this? WHen I change the order of inheritance for CScoreZone, it works fine
class CScorezone : public IPhysicsObject, public IBoardFeature
I'm running on VS2005 SP2 (8.0.50727.768) on Windows XP. Any ideas?
You don't have to assign CScorezone* to void* and then cast it to IPhysicsObject*. Since CScorezone is-a IPhysicsObject you can simply assign to base pointer:
IPhysicsObject *scoreZone = new CScorezone();
IPhysicsObject *otherZone = new CScorezone();
You're also missing public virtual destructor in IPhysicsObject declaration.
Edit:
I a callback situation as you describe in the comments (going through some C api?) I'd use simple struct with a pointer to polymorphic type to avoid undefined casts, something like:
// one more level of indirection
struct cb_data
{
IPhysicsObject* target;
};
// callback function
int callback( void* data )
{
const cb_data& cbd( *static_cast<cb_data*>( data ));
return cbd.target->Collide( ... );
}
The problem is that you cast the pointer to void* first.
The compiler doesn't know then how to perform static cast for the pointer.
It needs to change the pointer value during the cast if you use multiple inheritance to use second superclass virtual table.
Just cast the pointer back to CScoreZone* before using static_cast.
Well, in your code you seem to be deliberately destroying the integrity of a hierarchical cast by using void * as an intermediate type in the cast. ScoreZone * is cast to void * first and then cast to IPhysicsObject *. What you get as the result is undefined behavior.
Why are you doing this? And what did you expect will happen?
Nikolai told you how to avoid casting in the first place with your example given. However if you do need to do a typecast, when working with objects always use dynamic_cast, which does runtime type checking.