Virtual functions in C [duplicate] - c

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How could one implement C++ virtual functions in C
In C++ the only difference between a class and a struct is the default access level. So you can have virtual functions in structures, inherit from structures and so on. My question is, can you also do this in C?

You can do "virtual functions" with function pointers stored in your structs. For inheratince, you can embed a struct in another struct but the syntax, again, is going to be different than what you would expect. You can write object-oriented programs in C (classic example is the unix file/socket/... API), but with a quite awkward syntax.
Relevant answers here: https://stackoverflow.com/search?q=C+virtual+functions

C has no native syntax for virtual methods. However, you can still implement virtual methods by mimicking the way C++ implements virtual methods. C++ stores an additional pointer to the function definition in each class for each virtual method. Thus, you can simply add a function pointer to a struct to simulate virtual methods.
For example
#include <stdio.h>
#include <stdlib.h>
int f2(int x)
{
printf("%d\n",x);
}
typedef struct mystruct
{
int (*f)(int);
} mystruct;
int main()
{
mystruct *s=malloc(sizeof(mystruct));
s->f=f2;
s->f(42);
free(s);
return 0;
}

No you can't. 'virtual' is not part of the C vocabulary, neither is 'access level'

You can simulate virtual functions with function pointers. For instance,
struct foo
{
void(*bar)(struct foo*, int, int);
};
void default_bar ( struct foo * f, int a, int b )
{
printf("bar(%d,%d)\n", a, b);
}
void setup_foo ( struct foo * f )
{
f->bar = &default_bar;
}
Then, you can "subclasss" the structure with something like:
struct meh
{
/* inherit from "class foo". MUST be first. */
struct foo base;
int more_data;
};
/* override "method bar". */
struct custom_bar ( struct foo * f, int a, int b )
{
struct meh * m = (struct meh*)f;
printf("custom_bar(%d,%d)\n", a, b);
}
void setup_meh ( struct meh * m )
{
setup_foo(&m->base);
m->bar = &custom_bar;
}
All of this is labor-intensive and error prone, but it can be done. This type of "inheritance" and "override" implementation is common practice in some well-known C libraries, including jpeglib and libpng. They use this technique to allow you to override the I/O procedures if you're not satisfied with standard C I/O.
Edit: as noted in the comments, some of this code relies on (officially) non-standard behavior that "just happens" to work on most compilers. The main issue is that the code assumes that &m.base == &m (e.g. the offset of the base member is 0). If that is not the case, then the cast in custom_bar() results in undefined behavior. To work around this issue, you can add an extra pointer in struct foo as such:
struct foo
{
/* same as before ...*/
/* extra pointer. */
void * hook;
};
Then, modify the stuff that touches the cast,
void setup_meh ( struct meh * m )
{
m->base.hook = m;
/* set up function pointers as usual... */
}
void custom_bar ( struct foo * f, int a, int b )
{
struct meh * m = (struct meh*)f->hook;
/* override. */
}
This technique is more reliable, especially if you plan to write the "derived struct" in C++ and use virtual functions. In that case, the offset of the first member is often non-0 as compilers store run-time type information and the class' v-table there.

You can not. C structs can not have behaviors. They can only have data.
Please see http://www.topcoder.com/tc?module=Static&d1=tutorials&d2=tenBestQuestions
for differences between C structs and C++ structs.
it is written in the second question.
C++ structures is as different as C++ classes are different from C structs. It's just an analogy.
Plus there's no such thing as inheritence in C. Without inheritence, what would you do with virtual functions?

Related

ANSI C - Benefit of assigning alternative name to pointer type using typedef [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the right way to typedef a type and the same type's pointer?
I've recently been using Libxml2 in my project and noticed it uses typedefs like the following:
typedef struct _xmlNode xmlNode
typedef xmlNode * xmlNodePtr
The benefit of the first typedef is obvious. However I'm not sure why you'd assign an alternative name to xmlNode *. To me it's more explicit and readable to use xmlNode * than to use xmlNodePtr but I might be missing something.
What problems would this typedef solve and also what benefits would it bring?
C APIs often provide opaque handles, which discourage the consumer from asking what they are and attempting to poke inside. The fact that these handles are pointers is immaterial and should not matter to the consumer, nor should she be burdened with the lexical clutter of an extra star.
For example, it's perfectly possible to write a C++ binding by defining a handle:
typedef void * MyHandle;
Now we give the blissful C consumer some functions:
MyHandle create_gizmo();
void destroy_gizmo(MyHandle);
int do_magic(MyHandle, int, int);
Simple as that. The user immediately sees how to use it:
#include "MagicAPI.h"
MyHandle h = create_gizmo();
submit_result(do_magic(h, 12, 91));
destroy_gizmo(h);
And the C++ library developer simply unwraps the handle and populates the API functions (which are of course declared extern "C"):
#include "MagicAPI.h"
#include "SuperGizmo.hpp"
MyHandle create_gizmo() { return static_cast<MyHandle>(new SuperGizmo); }
void destroy_gizmo(MyHandle h) { delete static_cast<SuperGizmo *>(h); }
int do_magic(MyHandle h, int a, int b)
{
return static_cast<SuperGizmo *>(h)->foo(a, b);
}
What problems would this typedef solve and also what benefits would it bring?
My opinion is typedefing object pointers is bad and should not be done.
First it alters the grammar of the C language by hiding that the declared object is of a pointer type.
Second type qualifiers (const and volatile) cannot penetrate a typedef.
If we take your example:
typedef struct _xmlNode xmlNode;
typedef xmlNode * xmlNodePtr;
It is now impossible to declare an object so the pointee is const using xmlNodePtr alias.
const xmlNodePtr xp;
means xp is const not *xp.
const xmlNode x = /* ... */;
const xmlNodePtr xp = &x; // Error!
By the way in the Linux kernel coding style they also recommend not to use typedef for pointers:
"It's a mistake to use typedef for structures and pointers."
For some people a typedef with "ptr" in the name is more readable and "natural" than declarations using normal pointer syntax. If you like writing
foo* p;
instead of
foo *p;
then the pointer typedef likely appeals to you because it specifically avoids the error of writing
foo* p, q;
when you meant
foo *p, *q;
Instead you can write
fooptr p, q;
There are a few differences.
Firstly, if you're doing multiple declarations in one line, the following two snippets are equivalent:
char *c1, *c2, *c3, *c4;
typedef char * charPtr;
charPtr c1, c2, c3, c4; // I don't need to repeat the unary * everywhere
This is useful in part because you might run into semantical issues from trying to do something like:
char * c1, c2, c3, c4; // declares one char pointer and three chars
Secondly, they can drastically simplify definitions of function pointer types, which are opportunities for almost infinite ugliness and nastiness.
float (*someCrazyFunction)(float(*)(), float) = foo; // WTF is this
typedef float (*crazyFunction)(float(*)(), float);
crazyFunction myCrazyFunction = foo; // easier to deal with
Here's an ideone demonstrating all of this behavior.

Using pointer functions to emulate member functions in C structs

So just for the sake if having ''fun'' I decided to emulate C++ member functions in C using pointer functions. Here is a simple code:
obj.h:
#ifndef OBJ_H
#define OBJ_H
#include <stdlib.h>
#include <stdio.h>
struct Obj{
struct pObjVar* pVar;
void (*read)(struct Obj*);
void (*set) (struct Obj*, int);
};
struct Obj* newObj();
void deleteObj(struct Obj** obj);
#endif
obj.c:
#include "obj.h"
void readValue(struct Obj* this_);
void setValue (struct Obj* this_, int mValue_);
struct pObjVar{
int mValue;
};
struct Obj* newObj(){
struct Obj* tmp = (struct Obj*) malloc(sizeof(struct Obj));
tmp->pVar = (struct pObjVar*) malloc(sizeof(struct pObjVar));
tmp->pVar->mValue = 0;
tmp->read = readValue;
tmp->set = setValue;
return tmp;
}
void deleteObj(struct Obj **obj){
free((*obj)->pVar); (*obj)->pVar = NULL;
free((*obj)); *obj = NULL;
}
void readValue(struct Obj *this_){
printf("Value = %d\n",this_->pVar->mValue);
}
void setValue(struct Obj *this_, int mValue_){
this_->pVar->mValue = mValue_;
}
main.c:
#include "obj.h"
int main(void)
{
struct Obj* a = newObj();
a->set(a, 10);
a->read(a);
deleteObj(&a);
return 0;
}
Output:
>./a.out
Value = 10
In doing this, however, I figured I had to emulate the role of implicit this pointer by explicitly passing it to my member functions. This works fine, I guess, except that it makes the whole thing look weird!
If I wanted to pass the object, why would implement the functions as member functions? The only answer I found to it was maybe in cases where you would want to have a unified interface but various implementations? (something similar to C++ virtual functions?)
What are (if any) some other reasons to emulate member functions? Also, is there any way to get around passing the explicit this_ pointer at all?
EDIT: There was problem in the original code when passing the object. I was using &a by mistake for the read/set functions. You would only need it for the deleteObj if you want to set the pointer to NULL internally.
Just another way of writing:
#define member(FUNC, ...) FUNC(this_, ## __VA_ARGS__)
int reader(struct Obj *_this) {
member(read, a, b, c);
member(getch);
return 0;
}
This can be used for implementing interfaces, inheritance and many C++ features, which were implemented like this in C with Classes times. In Linux kernel, file operations are implemented like this. File structure stores pointers to functions, so that each file system can store it's own system call handlers that operate on/with the data in the structure.
No, there is no way to do this automatically in C. The standard preprocessor is not competent enough to do the transformations.
There is also now way for a function to find out that it was called like a->func(10). Inside the function it is just func(10).
When Bjarne Stroustrup started designing C++, he wrote a special preprocessor/compiler Cfront for this.
In reality, C++ doesn't really store pointers to (non-virtual) functions. It just transforms a->set(10) to something like struct_Obj_set(a, 10) while compiling the code.

C find which pointer called function

Scenario:
There are multiple C structs, each of which contains a function pointer to the same function. These pointers can be different if necessary (pointers to pointers, etc.), but must all point, eventually, to the same function.
Problem:
When the function is called from one of the pointers, I need to retrieve, within the function, which struct it was called from.
e.g.
typedef struct A {
void * (*func)();
... /* Custom properties */
} * A;
typedef struct B {
void * (*func)();
... /* Custom properties */
} * B;
A a_init() {
A a;
... /* Custom initialisation, allocation, etc. */
a->func = myFunc;
return a;
}
B b_init() {
B b;
... /* Custom initialisation, allocation, etc. */
b->func = myFunc;
return b;
}
int main () {
A a = a_init();
void *something = a->func();
}
void * myFunc () {
// Need to get pointer to the instance of the struct this was called from here
}
Is there any way I can retrieve a pointer to the caller within myFunc? If necessary, I was thinking of creating pointers to pointers, etc. to the function, so each instance of an object would have a different pointer, and store all of them in a central location to match them up, but that obviously won't work if I can't even find the instance of the object or the pointer which was used. Any ideas?
Edit:
The question was intended a bit more broadly than I seem to have put it. Currying would be a great solution, if anyone has any ideas as to how to implement it in C. I had some ideas, but I just ended up coming right back to this spot with it.
I don't think there is any way within the language to do that, without explicitly passing some identifier (as an argument or a global) to myFunc. The address of a_init() exists somwhere within the call stack, but it's not accessible from the program.
It's like if somebody showed up at your door unannounced, how would you find out where that person came from without asking?
You can't do that. What you may do, however, is define your structs like this:
typedef struct A {
/* ... */
void *(*func)(void *);
} A;
typedef struct B {
/* ... */
void *(*func)(void *);
} B;
And your function like this:
void *myFunc(void *the_struct) {
/* ... */
}
And call like this:
A a = a_init();
void *something = a->func(a);
Alternatively, if you don't care about portability and for some reason need to be able to call it like a->func(), you may be able to create thunks/trampolines that add in the argument.
Can't be done.
In C++ when you call member functions the compiler implicitly adds this as the first function argument. Mimicking obj->method() syntax in C won't work because there's no implicit this.
This doesn't mean that OO is impossible in C, simply that you can't use the same syntax as C++ or Java do to it. It can still be done, but you have to be explicit:
void * myFunc (void *this) {
...
}
a->func(a);
b->func(b);

How to achieve encapsulation in C

I am not sure that what I am trying to do is called encapsulation, but it's an OOP concept. I am implementing a binary tree and in particular the insert function:
typedef struct __node* tree;
typedef struct __node { void* data; tree l,r; } node;
typedef struct {int (*cmp)(void* a,void* b); tree root;} avl_tree;
....
void tree_insert(tree node, tree* root, int (*cmp)(void* a,void* b))
{
if (*root==NULL) { *root=node; return; }
int c1 = cmp(node->data, (*root)->data);
if (c1==-1) tree_insert(node, &((*root)->l), cmp);
}
tree tree_new_node(void*data){ tree a = malloc(...); ... return a; }
void avl_insert(void* data, avl_tree* a)
{
tree_insert(tree_new_node(data), &(a->root), a->cmp);
....
}
The module is to be used through the avl_insert function which is given a pointer to the relevant balanced tree avl_tree which contains the pointer to the raw tree as well as a pointer to comparator. Now, it should obviously call tree insert and tree_insert should have access to the comparator as well as to the node I am currently inserting. The function walks on a binary tree so it's naturally recursive. However, if I give it the comparator and the current node as parameters they will be passed with each recursive invocation which is not necessary since they will always be the same.
I would like to avoid having to do so. I have not been able to come up with a clean and nice solution. These are the options that I could think of:
Use a C++ class and have the tree_insert function be a method of avl_tree class. Then it would have access to the comparator through the this pointer. The problem with this solution is that I want to use C not C++. Besides, it won't eliminate the passing of the current node parameter.
Use static members inside the function (or global data). I am not sure I can cleanly initialize them at each avl_insert call. Besides, this solution is not thread safe.
Now that I think about it this seems very easy to implement in a functional programming language. I wonder, is this a fundamental problem with C or is it just me not knowing how to do it. What would be the cleanest way to achieve this?
Thank you!
After I thought about Victor Sorokin's answer I read about the this pointer and it turns out it is an implicit parameter in every member function call. Now that I think about it it seems the only logical solution. Each invocation of the tree_insert function needs to know the address of the structure it's operating on. Not even in a functional language could you avoid that extra pointer...
A possible solution would be to keep a pointer to the main tree structure in each node..
So it's a fundamental "problem".
One fun approach that could be used to achieve encapsulation is looking into assembly code emitted by C++ compiler and then translating it into appropriate C code.
Another, more conventional, approach would be to use some C object library, like GLib.
I think, though, these two methods will give similar results :)
By the way, first option you mentioned is just as vulnerable to threading issues as second. There's no implicit thread-safety in C++.
"OOP" C code I have seen in Linux kernel (file-system layer) is mostly concerned with polymorphism, not with encapsulation. Polymorphism is achieved by introducing structure enumerating possible operations (as pointers to functions). Various "subclasses" then created, each initializing this structure with it's own set of implementation methods.
You should be able to convert that tail recursion to iteration, and avoid the function calls altogether. Something like
void tree_insert(tree node,tree*root,int (*cmp)(void*a,void*b))
{
tree* current = root;
while (*current != NULL)
{
int c1=cmp(node->data,(*current)->data);
if(c1==-1)current = &((*current)->l);
else current = &((*current)->r);
}
*current=node;
}
There is already a question covering my answer—What does “static” mean in a C program?
You can roughly take a C source file as a class. The keyword static makes the variable or function have only internal linkage, which is similar to private in classical OOP.
foo.h
#ifndef FOO_H
#define FOO_H
double publicStuff;
double getter (void);
void setter (double);
int publicFunction (void);
#endif
foo.c
#include "foo.h"
static double privateStuff;
static int privateFunction (void)
{
return privateStuff;
}
int publicFunction (void)
{
return privateFunction();
}
double getter (void)
{
return privateStuff;
}
void setter (double foo)
{
privateStuff = foo;
}
main.c
#include "foo.h"
#include <stdio.h>
static double privateStuff = 42;
static int privateFunction (void)
{
return privateStuff;
}
int main (void)
{
publicStuff = 3.14;
setter(publicStuff);
printf("%g %d %d\n", getter(), publicFunction(), privateFunction());
return 0;
}

C as an object oriented language

Could you suggest a syntax for the C language to use it in a similar way than an object-oriented language? I know that they cannot be the same and that some keywords aren't present in C, but I'm wondering if there is a way to take advantage of certain aspects (like inheritance) even in a C program.
You can implement polymorphism with regular functions and virtual tables (vtables). Here's a pretty neat system that I invented (based on C++) for a programming exercise:
(source: goblin.tkk.fi)
The constructors allocate memory and then call the class' init function where the memory is initialized. Each init function should also contain a static vtable struct that contains the virtual function pointers (NULL for pure virtual). Derived class init functions call the superclass init function before doing anything else.
A very nice API can be created by implementing the virtual function wrappers (not to be confused with the functions pointed to by the vtables) as follows (add static inline in front of it, if you do this in the header):
int playerGuess(Player* this) { return this->vtable->guess(this); }
Single inheritance can be done by abusing the binary layout of a struct:
(source: goblin.tkk.fi)
Notice that multiple inheritance is messier as then you often need to adjust the pointer value when casting between types of the hierarchy.
Other type-specific data can be added to the virtual tables as well. Examples include runtime type info (e.g. type name as a string), linking to superclass vtable and the destructor chain. You probably want virtual destructors where derived class destructor demotes the object to its super class and then recursively calls the destructor of that and so on, until the base class destructor is reached and that finally frees the struct.
There is the GObject library:
The GLib Object System, or GObject, is a free software library (covered by the LGPL) that provides a portable object system and transparent cross-language interoperability. GObject is designed for use both directly in C programs and through bindings to other languages.
The traditional solution is the function pointer struct. I emphasize traditional. I can tell you what sort of code I wrote in PL/I and C years ago, but I don't claim to speak for the state of the 'art' if you can call this art.
There are many variations on this, and the below is a bit of a compromise.
struct SortOfAnAbstractClass {
int (*function1)(SortOfAnAbstractClass* this, int arg1, int arg2, char * arg3);
void (*function2)(SortOfAnAbstractClass* this, char *arg);
};
struct SortOfDerived {
struct SortOfAnAbstractClass base;
int instanceVariable1;
};
SortOfAnAbstractClass getMeOne() {
SortOfDerived *d = malloc(sizeof SortOfDerived);
memset(d, 0, sizeof SortOfDerived);
d->function1 = myf1;
d->function2 = myf2;
return &d->base;
};
and then 'myf1' and 'myf2' cast their 'this' parameters and go to town. You can extend this to look ever more like a full virtual dispatch.
Another common variation from the mists of time:
struct SortOfAClass {
void *creatorInfo;
int (*function1)(SortOfAnAbstractClass* this, int arg1, int arg2, char * arg3);
void (*function2)(SortOfAnAbstractClass* this, char *arg);
};
In this variation, there's no inheritance by inclusion. The derived classes each put their private state into their own object in creatorInfo.
Take a look at the GObject library: http://library.gnome.org/devel/gobject/2.22/.
There are many variations to doing OO programming in C. The way I prefer to do it is to define one class per a header file. You'll notice a constructor new_testclass() which just initializes your function pointers and returns a pointer to an allocated class/struct. Also any function takes pointer to the class in the first parameter (something c++ does, but conceals).
testclass.h
#ifndef MALLOC_H
#include<malloc.h>
#endif
struct _testclass
{
int a;
int b;
int (*sum)(struct _testclass *obj);
};
typedef struct _testclass testclass;
int f_sum (testclass *obj)
{
return obj->a + obj->b;
}
testclass* new_testclass()
{
testclass *temp;
temp = (testclass*)malloc(sizeof(testclass));
temp->sum = &f_sum;
return temp;
}
Then you can simply use it.
testclass.c
#include <stdio.h>
#include "testclass.h"
int _tmain(int argc, _TCHAR* argv[])
{
int result;
testclass *testclass1;
testclass1 = new_testclass();
testclass1->a = 5;
testclass1->b = 8;
result = testclass1->sum(testclass1);
printf("%d\n",result);
free(testclass1);
return 0;
}
Of course there are several important aspects of object oriented programming missing here, but this provides a simple method for basic abstraction. I'd imagine inheritance would require some kind of funky preprocessor trick if it could be done at all.

Resources