gjditchfield@watmsg.waterloo.edu (Glen Ditchfield) (04/18/88)
More news from the frontiers of compiler abuse... I want to call an unusual C function from C++. Calls look like result = emit(fptr, size, p1, ... pn) where fptr is a pointer to a function that may return an integer or void, and size is an integer. emit() calls fptr and passes it p1, .. pn as arguments. (emit() is part of a light-weight task library.) I want to pass a virtual function through fptr. How do I phrase the call? So far, I have found four ways that don't work. One of these causes an internal cfront error, and one causes the C compiler to produce errors. ---------------------------------------- typedef int procid; extern procid emit(...); extern int absorb(procid); extern int cprintf(char*, ...); // ...for serialized printing. class task { procid pid; public: virtual void body(); task(int stacksize); ~task(); }; task::~task() { absorb(pid); }; task::task(int stacksize) { pid = emit( &body, stacksize, this); //"err2.cc", line 23: warning: address of bound function (try task ::* pointer type and &task ::body address) }; void task::body() { cprintf("Error: no task body specified.\n"); }; class test:public task { public: test():(2000){}; void body(); }; void test::body() { cprintf("Test body executed.\n"); }; main() { test t; }; This version prints "Error: no task body specified." It's calling the wrong body(). ---------------------------------------- If I heed the warning message and change task::task() to task::task(int stacksize) { pid = emit( &task::body, stacksize, this); }; The c code generated by cfront for the above is _au0_this -> _task_pid = emit ( ((char (*)())1), _au0_stacksize , _au0_this ) ; which isn't what I intended. Is this really the way pointers to virtual functions are implemented? ---------------------------------------- A bug: change it to task::task(int stacksize) { pid = emit( body, stacksize, this); }; and I get cc err3..c /usr/lib/libccc.a "err3.cc", line 27: "_task_body" undefined "err3.cc", line 27: member of structure or union required "err3.cc", line 27: value of void expression used ---------------------------------------- A bug: change it to task::task(int stacksize) { typedef void (task::*PVVMF)(); PVVMF pmf = &task::body; pid = emit( this->*pmf, stacksize, this); }; "err1.cc", line 26: internal <<cfront 1.2.1 2/16/87>> error: 299920-> expression::print .* ---------------------------------------- Glen Ditchfield {watmath,utzoo,ihnp4}!watrose!gjditchfield Dept of Computer Science, U of Waterloo (519) 885-1211 x6658 Waterloo, Ontario, Canada Office: MC 2006 If you grab the bull by the horns, you at least confuse him -- R.A.Heinlein -- Glen Ditchfield {watmath,utzoo,ihnp4}!watrose!gjditchfield Dept of Computer Science, U of Waterloo (519) 885-1211 x6658 Waterloo, Ontario, Canada Office: MC 2006 If you grab the bull by the horns, you at least confuse him -- R.A.Heinlein