Related
I was experimenting with C11 and VLAs, trying to declare a struct variable on the stack with only an incomplete declaration. The objective is to provide a mechanism to create a variable of some struct type without showing the internals (like the PIMPL idiom) but without the need to create the variable on the heap and return a pointer to it. Also, if the struct layout changes, I don't want to recompile every file that uses the struct.
I have managed to program the following:
private.h:
#ifndef PRIVATE_H_
#define PRIVATE_H_
typedef struct A{
int value;
}A;
#endif /* PRIVATE_H_ */
public.h:
#ifndef PUBLIC_H_
#define PUBLIC_H_
typedef struct A A;
size_t A_getSizeOf(void);
void A_setValue(A * a, int value);
void A_printValue(A * a);
#endif /* PUBLIC_H_ */
implementation.c:
#include "private.h"
#include "stdio.h"
size_t A_getSizeOf(void)
{
return sizeof(A);
}
void A_setValue(A * a, int value)
{
a->value = value;
}
void A_printValue(A * a)
{
printf("%d\n", a->value);
}
main.c:
#include <stdalign.h>
#include <stddef.h>
#include "public.h"
#define createOnStack(type, variable) \
alignas(max_align_t) char variable ## _stack[type ## _getSizeOf()]; \
type * variable = (type *)&variable ## _stack
int main(int argc, char *argv[]) {
createOnStack(A, var);
A_setValue(var, 5335);
A_printValue(var);
}
I have tested this code and it seems to work. However I'm not sure if I'm overlooking something (like aliasing, alignment or something like that) that could be dangerous or unportable, or could hurt performance. Also I want to know if there are better (portable) solutions to this problem in C.
This of course violates the effective typing rules (aka strict aliasing) because the C language does not allow an object of tye char [] to be accessed through a pointer that does not have that type (or a compatible one).
You could disable strict aliasing analysis via compiler flags like -fno-strict-aliasing or attributes like
#ifdef __GNUC__
#define MAY_ALIAS __attribute__((__may_alias__))
#else
#define MAY_ALIAS
#endif
(thanks go to R.. for pointing out the latter), but even if you do not do so, in practice everything should work just fine as long as you only ever use the variable's proper name to initialize the typed pointer.
Personally, I'd simplify your declarations to something along the lines of
#define stackbuffer(NAME, SIZE) \
_Alignas (max_align_t) char NAME[SIZE]
typedef struct Foo Foo;
extern const size_t SIZEOF_FOO;
stackbuffer(buffer, SIZEOF_FOO);
Foo *foo = (void *)buffer;
The alternative would be using the non-standard alloca(), but that 'function' comes with its own set of issues.
I am considering adopting a strategy similar to the following to solve essentially the same problem. Perhaps it will be of interest despite being a year late.
I wish to prevent clients of a struct from accessing the fields directly, in order to make it easier to reason about their state and easier to write reliable design contracts. I'd also prefer to avoid allocating small structures on the heap. But I can't afford a C11 public interface - much of the joy of C is that almost any code knows how to talk to C89.
To that end, consider the adequate application code:
#include "opaque.h"
int main(void)
{
opaque on_the_stack = create_opaque(42,3.14); // constructor
print_opaque(&on_the_stack);
delete_opaque(&on_the_stack); // destructor
return 0;
}
The opaque header is fairly nasty, but not completely absurd. Providing both create and delete functions is mostly for the sake of consistency with structs where calling the destructor actually matters.
/* opaque.h */
#ifndef OPAQUE_H
#define OPAQUE_H
/* max_align_t is not reliably available in stddef, esp. in c89 */
typedef union
{
int foo;
long long _longlong;
unsigned long long _ulonglong;
double _double;
void * _voidptr;
void (*_voidfuncptr)(void);
/* I believe the above types are sufficient */
} alignment_hack;
#define sizeof_opaque 16 /* Tedious to keep up to date */
typedef struct
{
union
{
char state [sizeof_opaque];
alignment_hack hack;
} private;
} opaque;
#undef sizeof_opaque /* minimise the scope of the macro */
void print_opaque(opaque * o);
opaque create_opaque(int foo, double bar);
void delete_opaque(opaque *);
#endif
Finally an implementation, which is welcome to use C11 as it's not the interface. _Static_assert(alignof...) is particularly reassuring. Several layers of static functions are used to indicate the obvious refinement of generating the wrap/unwrap layers. Pretty much the entire mess is amenable to code gen.
#include "opaque.h"
#include <stdalign.h>
#include <stdio.h>
typedef struct
{
int foo;
double bar;
} opaque_impl;
/* Zero tolerance approach to letting the sizes drift */
_Static_assert(sizeof (opaque) == sizeof (opaque_impl), "Opaque size incorrect");
_Static_assert(alignof (opaque) == alignof (opaque_impl), "Opaque alignment incorrect");
static void print_opaque_impl(opaque_impl *o)
{
printf("Foo = %d and Bar = %g\n",o->foo,o->bar);
}
static void create_opaque_impl(opaque_impl * o, int foo, double bar)
{
o->foo = foo;
o->bar = bar;
}
static void create_opaque_hack(opaque * o, int foo, double bar)
{
opaque_impl * ptr = (opaque_impl*)o;
create_opaque_impl(ptr,foo,bar);
}
static void delete_opaque_impl(opaque_impl *o)
{
o->foo = 0;
o->bar = 0;
}
static void delete_opaque_hack(opaque * o)
{
opaque_impl * ptr = (opaque_impl*)o;
delete_opaque_impl(ptr);
}
void print_opaque(opaque * o)
{
return print_opaque_impl((opaque_impl*)o);
}
opaque create_opaque(int foo, double bar)
{
opaque tmp;
unsigned int i;
/* Useful to zero out padding */
for (i=0; i < sizeof (opaque_impl); i++)
{
tmp.private.state[i] = 0;
}
create_opaque_hack(&tmp,foo,bar);
return tmp;
}
void delete_opaque(opaque *o)
{
delete_opaque_hack(o);
}
The drawbacks I can see myself:
Changing the size define manually would be irritating
The casting should hinder optimisation (I haven't checked this yet)
This may violate strict pointer aliasing. Need to re-read the spec.
I am concerned about accidentally invoking undefined behaviour. I would also be interested in general feedback on the above, or whether it looks like a credible alternative to the inventive VLA technique in the question.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How can I simulate OO-style polymorphism in C?
I'm trying to better understand the idea of polymorphism with examples from languages I know;
is there polymorphism in C?
This is Nekuromento's second example, factored in the way I consider idiomatic for object-oriented C:
animal.h
#ifndef ANIMAL_H_
#define ANIMAL_H_
struct animal
{
// make vtable_ a pointer so they can be shared between instances
// use _ to mark private members
const struct animal_vtable_ *vtable_;
const char *name;
};
struct animal_vtable_
{
const char *(*sound)(void);
};
// wrapper function
static inline const char *animal_sound(struct animal *animal)
{
return animal->vtable_->sound();
}
// make the vtables arrays so they can be used as pointers
extern const struct animal_vtable_ CAT[], DOG[];
#endif
cat.c
#include "animal.h"
static const char *sound(void)
{
return "meow!";
}
const struct animal_vtable_ CAT[] = { { sound } };
dog.c
#include "animal.h"
static const char *sound(void)
{
return "arf!";
}
const struct animal_vtable_ DOG[] = { { sound } };
main.c
#include "animal.h"
#include <stdio.h>
int main(void)
{
struct animal kitty = { CAT, "Kitty" };
struct animal lassie = { DOG, "Lassie" };
printf("%s says %s\n", kitty.name, animal_sound(&kitty));
printf("%s says %s\n", lassie.name, animal_sound(&lassie));
return 0;
}
This is an example of runtime polymorphism as that's when method resolution happens.
C1x added generic selections, which make compile-time polymorphism via macros possible. The following example is taken from the C1x April draft, section 6.5.1.1 §5:
#define cbrt(X) _Generic((X), \
long double: cbrtl, \
default: cbrt, \
float: cbrtf \
)(X)
Type-generic macros for math functions were already available in C99 via the header tgmath.h, but there was no way for users to define their own macros without using compiler extensions.
Almost all implementations of runtime polymorphism in C will use function pointers, so this is the basic building block.
Here is a simple example when procedure runtime behavior changes depending on it's argument.
#include <stdio.h>
int tripple(int a) {
return 3 * a;
}
int square(int a) {
return a * a;
}
void transform(int array[], size_t len, int (*fun)(int)) {
size_t i = 0;
for(; i < len; ++i)
array[i] = fun(array[i]);
}
int main() {
int array[3] = {1, 2, 3};
transform(array, 3, &tripple);
transform(array, 3, &square);
size_t i = 0;
for (; i < 3; ++i)
printf("%d ", array[i]);
return 0;
}
Using function pointers you can create virtual tables and use it to create "objects" that will be treated uniformly, but behave differently at runtime.
#include <stdio.h>
struct animal_vtable {
const char* (*sound)();
};
struct animal {
struct animal_vtable methods;
const char* name;
};
const char* cat_sound() {
return "meow!";
}
const char* dog_sound() {
return "bark!";
}
void describe(struct animal *a) {
printf("%s makes \"%s\" sound.\n", a->name, a->methods.sound());
}
struct animal cat = {{&cat_sound}, "cat"};
struct animal dog = {{&dog_sound}, "dog"};
int main() {
describe(&cat);
describe(&dog);
return 0;
}
There's no intrinsic support for polymorphism in C, but there are design patterns, using function pointers, base 'class' (structure) casts, etc., that can provide a logical equivalent of dynamic dispatch. The GTK library is good example.
I guess, you already checked Wikipedia article on polymorphism.
In computer science, polymorphism is a programming language feature
that allows values of different data types to be handled using a
uniform interface.
According to that definition, no, C doesn't natively support polymorphism. For instance, there is no general function for acquiring absolute value of a number (abs and fabs are for integers and doubles respectively).
If you're also familiar with C++, take a look at OOP inheritance and templates - those are mechanisms for polymorphism there.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
For example, I recently came across this in the linux kernel:
/* Force a compilation error if condition is true */
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
So, in your code, if you have some structure which must be, say a multiple of 8 bytes in size, maybe because of some hardware constraints, you can do:
BUILD_BUG_ON((sizeof(struct mystruct) % 8) != 0);
and it won't compile unless the size of struct mystruct is a multiple of 8, and if it is a multiple of 8, no runtime code is generated at all.
Another trick I know is from the book "Graphics Gems" which allows a single header file to both declare and initialize variables in one module while in other modules using that module, merely declare them as externs.
#ifdef DEFINE_MYHEADER_GLOBALS
#define GLOBAL
#define INIT(x, y) (x) = (y)
#else
#define GLOBAL extern
#define INIT(x, y)
#endif
GLOBAL int INIT(x, 0);
GLOBAL int somefunc(int a, int b);
With that, the code which defines x and somefunc does:
#define DEFINE_MYHEADER_GLOBALS
#include "the_above_header_file.h"
while code that's merely using x and somefunc() does:
#include "the_above_header_file.h"
So you get one header file that declares both instances of globals and function prototypes where they are needed, and the corresponding extern declarations.
So, what are your favorite C programming tricks along those lines?
C99 offers some really cool stuff using anonymous arrays:
Removing pointless variables
{
int yes=1;
setsockopt(yourSocket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
}
becomes
setsockopt(yourSocket, SOL_SOCKET, SO_REUSEADDR, (int[]){1}, sizeof(int));
Passing a Variable Amount of Arguments
void func(type* values) {
while(*values) {
x = *values++;
/* do whatever with x */
}
}
func((type[]){val1,val2,val3,val4,0});
Static linked lists
int main() {
struct llist { int a; struct llist* next;};
#define cons(x,y) (struct llist[]){{x,y}}
struct llist *list=cons(1, cons(2, cons(3, cons(4, NULL))));
struct llist *p = list;
while(p != 0) {
printf("%d\n", p->a);
p = p->next;
}
}
Any I'm sure many other cool techniques I haven't thought of.
While reading Quake 2 source code I came up with something like this:
double normals[][] = {
#include "normals.txt"
};
(more or less, I don't have the code handy to check it now).
Since then, a new world of creative use of the preprocessor opened in front of my eyes. I no longer include just headers, but entire chunks of code now and then (it improves reusability a lot) :-p
Thanks John Carmack! xD
I'm fond of using = {0}; to initialize structures without needing to call memset.
struct something X = {0};
This will initialize all of the members of the struct (or array) to zero (but not any padding bytes - use memset if you need to zero those as well).
But you should be aware there are some issues with this for large, dynamically allocated structures.
If we are talking about c tricks my favourite has to be Duff's Device for loop unrolling! I'm just waiting for the right opportunity to come along for me to actually use it in anger...
using __FILE__ and __LINE__ for debugging
#define WHERE fprintf(stderr,"[LOG]%s:%d\n",__FILE__,__LINE__);
In C99
typedef struct{
int value;
int otherValue;
} s;
s test = {.value = 15, .otherValue = 16};
/* or */
int a[100] = {1,2,[50]=3,4,5,[23]=6,7};
Once a mate of mine and I redefined return to find a tricky stack corruption bug.
Something like:
#define return DoSomeStackCheckStuff, return
I like the "struct hack" for having a dynamically sized object. This site explains it pretty well too (though they refer to the C99 version where you can write "str[]" as the last member of a struct). you could make a string "object" like this:
struct X {
int len;
char str[1];
};
int n = strlen("hello world");
struct X *string = malloc(sizeof(struct X) + n);
strcpy(string->str, "hello world");
string->len = n;
here, we've allocated a structure of type X on the heap that is the size of an int (for len), plus the length of "hello world", plus 1 (since str1 is included in the sizeof(X).
It is generally useful when you want to have a "header" right before some variable length data in the same block.
Object oriented code with C, by emulating classes.
Simply create a struct and a set of functions that take a pointer to that struct as a first parameter.
Instead of
printf("counter=%d\n",counter);
Use
#define print_dec(var) printf("%s=%d\n",#var,var);
print_dec(counter);
Using a stupid macro trick to make record definitions easier to maintain.
#define COLUMNS(S,E) [(E) - (S) + 1]
typedef struct
{
char studentNumber COLUMNS( 1, 9);
char firstName COLUMNS(10, 30);
char lastName COLUMNS(31, 51);
} StudentRecord;
For creating a variable which is read-only in all modules except the one it's declared in:
// Header1.h:
#ifndef SOURCE1_C
extern const int MyVar;
#endif
// Source1.c:
#define SOURCE1_C
#include Header1.h // MyVar isn't seen in the header
int MyVar; // Declared in this file, and is writeable
// Source2.c
#include Header1.h // MyVar is seen as a constant, declared elsewhere
Bit-shifts are only defined up to a shift-amount of 31 (on a 32 bit integer)..
What do you do if you want to have a computed shift that need to work with higher shift-values as well? Here is how the Theora vide-codec does it:
unsigned int shiftmystuff (unsigned int a, unsigned int v)
{
return (a>>(v>>1))>>((v+1)>>1);
}
Or much more readable:
unsigned int shiftmystuff (unsigned int a, unsigned int v)
{
unsigned int halfshift = v>>1;
unsigned int otherhalf = (v+1)>>1;
return (a >> halfshift) >> otherhalf;
}
Performing the task the way shown above is a good deal faster than using a branch like this:
unsigned int shiftmystuff (unsigned int a, unsigned int v)
{
if (v<=31)
return a>>v;
else
return 0;
}
Declaring array's of pointer to functions for implementing finite state machines.
int (* fsm[])(void) = { ... }
The most pleasing advantage is that it is simple to force each stimulus/state to check all code paths.
In an embedded system, I'll often map an ISR to point to such a table and revector it as needed (outside the ISR).
Another nice pre-processor "trick" is to use the "#" character to print debugging expressions. For example:
#define MY_ASSERT(cond) \
do { \
if( !(cond) ) { \
printf("MY_ASSERT(%s) failed\n", #cond); \
exit(-1); \
} \
} while( 0 )
edit: the code below only works on C++. Thanks to smcameron and Evan Teran.
Yes, the compile time assert is always great. It can also be written as:
#define COMPILE_ASSERT(cond)\
typedef char __compile_time_assert[ (cond) ? 0 : -1]
I wouldn't really call it a favorite trick, since I've never used it, but the mention of Duff's Device reminded me of this article about implementing Coroutines in C. It always gives me a chuckle, but I'm sure it could be useful some time.
#if TESTMODE == 1
debug=1;
while(0); // Get attention
#endif
The while(0); has no effect on the program, but the compiler will issue a warning about "this does nothing", which is enough to get me to go look at the offending line and then see the real reason I wanted to call attention to it.
I'm a fan of xor hacks:
Swap 2 pointers without third temp pointer:
int * a;
int * b;
a ^= b;
b ^= a;
a ^= b;
Or I really like the xor linked list with only one pointer. (http://en.wikipedia.org/wiki/XOR_linked_list)
Each node in the linked list is the Xor of the previous node and the next node. To traverse forward, the address of the nodes are found in the following manner :
LLNode * first = head;
LLNode * second = first.linked_nodes;
LLNode * third = second.linked_nodes ^ first;
LLNode * fourth = third.linked_nodes ^ second;
etc.
or to traverse backwards:
LLNode * last = tail;
LLNode * second_to_last = last.linked_nodes;
LLNode * third_to_last = second_to_last.linked_nodes ^ last;
LLNode * fourth_to_last = third_to_last.linked_nodes ^ second_to_last;
etc.
While not terribly useful (you can't start traversing from an arbitrary node) I find it to be very cool.
This one comes from the book 'Enough rope to shoot yourself in the foot':
In the header declare
#ifndef RELEASE
# define D(x) do { x; } while (0)
#else
# define D(x)
#endif
In your code place testing statements eg:
D(printf("Test statement\n"));
The do/while helps in case the contents of the macro expand to multiple statements.
The statement will only be printed if '-D RELEASE' flag for compiler is not used.
You can then eg. pass the flag to your makefile etc.
Not sure how this works in windows but in *nix it works well
Rusty actually produced a whole set of build conditionals in ccan, check out the build assert module:
#include <stddef.h>
#include <ccan/build_assert/build_assert.h>
struct foo {
char string[5];
int x;
};
char *foo_string(struct foo *foo)
{
// This trick requires that the string be first in the structure
BUILD_ASSERT(offsetof(struct foo, string) == 0);
return (char *)foo;
}
There are lots of other helpful macros in the actual header, which are easy to drop into place.
I try, with all of my might to resist the pull of the dark side (and preprocessor abuse) by sticking mostly to inline functions, but I do enjoy clever, useful macros like the ones you described.
Two good source books for this sort of stuff are The Practice of Programming and Writing Solid Code. One of them (I don't remember which) says: Prefer enum to #define where you can, because enum gets checked by the compiler.
Not specific to C, but I've always liked the XOR operator. One cool thing it can do is "swap without a temp value":
int a = 1;
int b = 2;
printf("a = %d, b = %d\n", a, b);
a ^= b;
b ^= a;
a ^= b;
printf("a = %d, b = %d\n", a, b);
Result:
a = 1, b = 2
a = 2, b = 1
See "Hidden features of C" question.
I like the concept of container_of used for example in lists. Basically, you do not need to specify next and last fields for each structure which will be in the list. Instead, you append the list structure header to actual linked items.
Have a look on include/linux/list.h for real-life examples.
I think the use of userdata pointers is pretty neat. A fashion losing ground nowdays. It's not so much a C feature but is pretty easy to use in C.
I use X-Macros to to let the pre-compiler generate code. They are especially useful for defining error values and associated error strings in one place, but they can go far beyond that.
Our codebase has a trick similar to
#ifdef DEBUG
#define my_malloc(amt) my_malloc_debug(amt, __FILE__, __LINE__)
void * my_malloc_debug(int amt, char* file, int line)
#else
void * my_malloc(int amt)
#endif
{
//remember file and line no. for this malloc in debug mode
}
which allows for the tracking of memory leaks in debug mode. I always thought this was cool.
Fun with macros:
#define SOME_ENUMS(F) \
F(ZERO, zero) \
F(ONE, one) \
F(TWO, two)
/* Now define the constant values. See how succinct this is. */
enum Constants {
#define DEFINE_ENUM(A, B) A,
SOME_ENUMS(DEFINE_ENUMS)
#undef DEFINE_ENUM
};
/* Now a function to return the name of an enum: */
const char *ToString(int c) {
switch (c) {
default: return NULL; /* Or whatever. */
#define CASE_MACRO(A, B) case A: return #b;
SOME_ENUMS(CASE_MACRO)
#undef CASE_MACRO
}
}
Here is an example how to make C code completly unaware about what is actually used of HW for running the app. The main.c does the setup and then the free layer can be implemented on any compiler/arch. I think it is quite neat for abstracting C code a bit, so it does not get to be to spesific.
Adding a complete compilable example here.
/* free.h */
#ifndef _FREE_H_
#define _FREE_H_
#include <stdio.h>
#include <string.h>
typedef unsigned char ubyte;
typedef void (*F_ParameterlessFunction)() ;
typedef void (*F_CommandFunction)(ubyte byte) ;
void F_SetupLowerLayer (
F_ParameterlessFunction initRequest,
F_CommandFunction sending_command,
F_CommandFunction *receiving_command);
#endif
/* free.c */
static F_ParameterlessFunction Init_Lower_Layer = NULL;
static F_CommandFunction Send_Command = NULL;
static ubyte init = 0;
void recieve_value(ubyte my_input)
{
if(init == 0)
{
Init_Lower_Layer();
init = 1;
}
printf("Receiving 0x%02x\n",my_input);
Send_Command(++my_input);
}
void F_SetupLowerLayer (
F_ParameterlessFunction initRequest,
F_CommandFunction sending_command,
F_CommandFunction *receiving_command)
{
Init_Lower_Layer = initRequest;
Send_Command = sending_command;
*receiving_command = &recieve_value;
}
/* main.c */
int my_hw_do_init()
{
printf("Doing HW init\n");
return 0;
}
int my_hw_do_sending(ubyte send_this)
{
printf("doing HW sending 0x%02x\n",send_this);
return 0;
}
F_CommandFunction my_hw_send_to_read = NULL;
int main (void)
{
ubyte rx = 0x40;
F_SetupLowerLayer(my_hw_do_init,my_hw_do_sending,&my_hw_send_to_read);
my_hw_send_to_read(rx);
getchar();
return 0;
}
if(---------)
printf("hello");
else
printf("hi");
Fill in the blanks so that neither hello nor hi would appear in output.
ans: fclose(stdout)
Is there a way to write OO-like code in the C programming language?
See also:
Can you write object-oriented code in C?
Object-orientation in C
Found by searching on "[c] oo".
The first C++ compiler ("C with classes") would actually generate C code, so that's definitely doable.
Basically, your base class is a struct; derived structs must include the base struct at the first position, so that a pointer to the "derived" struct will also be a valid pointer to the base struct.
typedef struct {
data member_x;
} base;
typedef struct {
struct base;
data member_y;
} derived;
void function_on_base(struct base * a); // here I can pass both pointers to derived and to base
void function_on_derived(struct derived * b); // here I must pass a pointer to the derived class
The functions can be part of the structure as function pointers, so that a syntax like p->call(p) becomes possible, but you still have to explicitly pass a pointer to the struct to the function itself.
Common approach is to define struct with pointers to functions. This defines 'methods' which can be called on any type. Subtypes then set their own functions in this common structure, and return it.
For example, in linux kernel, there is struct:
struct inode_operations {
int (*create) (struct inode *,struct dentry *,int, struct nameidata *);
struct dentry * (*lookup) (struct inode *,struct dentry *,
struct nameidata *);
...
};
Each registered type of filesystem then registers its own functions for create, lookup, and remaining functions. Rest of code can than use generic inode_operations:
struct inode_operations *i_op;
i_op -> create(...);
C++ is not that far from C.
Classes are structures with a hidden pointer to a table of function pointers called VTable. The Vtable itself is static.
When types point to Vtables with the same structure but where pointers point to other implementation, you get polymorphism.
It is recommended to encapsulate the calls logic in function that take the struct as parameter to avoid code clutter.
You should also encapsulcte structures instantiation and initialisation in functions (this is equivalent to a C++ constructor) and deletion (destructor in C++). These are good practice anyway.
typedef struct
{
int (*SomeFunction)(TheClass* this, int i);
void (*OtherFunction)(TheClass* this, char* c);
} VTable;
typedef struct
{
VTable* pVTable;
int member;
} TheClass;
To call the method:
int CallSomeFunction(TheClass* this, int i)
{
(this->pVTable->SomeFunction)(this, i);
}
I looked at everyone elses' answers and came up with this:
#include <stdio.h>
typedef struct
{
int (*get)(void* this);
void (*set)(void* this, int i);
int member;
} TheClass;
int Get(void* this)
{
TheClass* This = (TheClass*)this;
return This->member;
}
void Set(void* this, int i)
{
TheClass* This = (TheClass*)this;
This->member = i;
}
void init(TheClass* this)
{
this->get = &Get;
this->set = &Set;
}
int main(int argc, char **argv)
{
TheClass name;
init(&name);
(name.set)(&name, 10);
printf("%d\n", (name.get)(&name));
return 0;
}
I hope that answers some questions.
Appendix B of the article Open Reusable Object Models, by Ian Piumarta and Alessandro Warth of VPRI is an implementation of an Object model in GNU C, about 140 lines of code. It's a fascinating read !
Here's the uncached version of the macro that sends messages to objects, using a GNU extension to C (statement expression):
struct object;
typedef struct object *oop;
typedef oop *(*method_t)(oop receiver, ...);
//...
#define send(RCV, MSG, ARGS...) ({ \
oop r = (oop)(RCV); \
method_t method = _bind(r, (MSG)); \
method(r, ##ARGS); \
})
In the same doc, have a look at the object, vtable, vtable_delegated and symbol structs, and the _bind and vtable_lookup functions.
Cheers!
What I usually like to do is to wrap the structs in another which contain meta information about the wrapped class and then build visitor like function lists acting on the generic struct. The advantage of this approach is that you don't need to modify the existing structures and you can create visitors for any subset of structs.
Take the usual example:
typedef struct {
char call[7] = "MIAO!\n";
} Cat;
typedef struct {
char call[6] = "BAU!\n";
} Dog;
We can wrap the 2 strutures in this new structure:
typedef struct {
const void * animal;
AnimalType type;
} Animal;
The type can be a simple int but let's not be lazy:
typedef enum {
ANIMAL_CAT = 0,
ANIMAL_DOG,
ANIMAL_COUNT
} AnimalType;
It would be nice to have some wrapping functions:
Animal catAsAnimal(const Cat * c) {
return (Animal){(void *)c, ANIMAL_CAT};
}
Animal dogAsAnimal(const Dog * d) {
return (Animal){(void *)d, ANIMAL_DOG};
}
Now we can define our "visitor":
void catCall ( Animal a ) {
Cat * c = (Cat *)a.animal;
printf(c->call);
}
void dogCall ( Animal a ) {
Dog * d = (Dog *)a.animal;
printf(d->call);
}
void (*animalCalls[ANIMAL_COUNT])(Animal)={&catCall, &dogCall};
Then the actual usage will be:
Cat cat;
Dog dog;
Animal animals[2];
animals[0] = catAsAnimal(&cat);
animals[1] = dogAsAnimal(&dog);
for (int i = 0; i < 2; i++) {
Animal a = animals[i];
animalCalls[a.type](a);
}
The disadvantage of this approach is that you have to wrap the structures every time you want to use it as a generic type.
The file functions fopen, fclose, fread are examples of OO code in C. Instead of the private data in class, they work on the FILE structure which is used to encapsulate the data and the C functions acts as an member class functions.
http://www.amazon.com/File-Structures-Object-Oriented-Approach-C/dp/0201874016
#include <stdio.h>
typedef struct {
int x;
int z;
} base;
typedef struct {
base;
int y;
int x;
} derived;
void function_on_base( base * a) // here I can pass both pointers to derived and to base
{
printf("Class base [%d]\n",a->x);
printf("Class base [%d]\n",a->z);
}
void function_on_derived( derived * b) // here I must pass a pointer to the derived class
{
printf("Class derived [%d]\n",b->y);
printf("Class derived [%d]\n",b->x);
}
int main()
{
derived d;
base b;
printf("Teste de poliformismo\n");
b.x = 2;
d.y = 1;
b.z = 3;
d.x = 4;
function_on_base(&b);
function_on_base(&d);
function_on_derived(&b);
function_on_derived(&d);
return 0;
}
The output was:
Class base [3]
Class base [1]
Class base [4]
Class derived [2]
Class derived [3]
Class derived [1]
Class derived [4]
so it works, its a polymorphic code.
UncleZeiv explained about it at the beginning.
From Wikipedia:
In programming languages and type theory, polymorphism (from Greek πολύς, polys, "many, much" and μορφή, morphē, "form, shape") is the provision of a single interface to entities of different types.
So I would say the only way to implement it in C is by using variadic arguments along with some (semi)automatic type info management.
For example in C++ you can write (sorry for trivialness):
void add( int& result, int a1, int a2 );
void add( float& result, float a1, float a2 );
void add( double& result, double a1, double a2 );
In C, among other solutions, the best you can do is something like this:
int int_add( int a1, int a2 );
float float_add( float a1, fload a2 );
double double_add( double a1, double a2 );
void add( int typeinfo, void* result, ... );
Then you need:
to implement the "typeinfo" with enums/macros
to implement the latter function with stdarg.h stuff
to say goodbye to C static type checking
I am almost sure that any other implementation of polymorphism should look much like this very one.
The above answers, instead, seems to try to address inheritance more than polymorphism!
In order too build OO functionality in C, you can look at previous answers.
But, (as it has been asked in other questions redirected to this one) if you want to understand what polymorphism is, by examples in C language. Maybe I am wrong, but I can't think of anything as easy to understand as C pointers arithmetic. In my opinion, pointer arithmetic is inherently polymorphic in C. In the following example the same function (method in OO), namely the addition (+), will produce a different behavior depending on the properties of the input structures.
Example:
double a*;
char str*;
a=(double*)malloc(2*sizeof(double));
str=(char*)malloc(2*sizeof(char));
a=a+2; // make the pointer a, point 2*8 bytes ahead.
str=str+2; // make the pointer str, point 2*1 bytes ahead.
Disclaimer: I am very new at C and very much looking forward to being corrected and learn from other user's comments, or even completely erase this answer, should it be wrong. Many thanks,
A very crude example of simple function overloading, much can be achieved using variadic macros.
#include <stdio.h>
#include <stdlib.h>
#define SCOPE_EXIT(X) __attribute__((cleanup (X)))
struct A
{
int a;
};
struct B
{
int a, b;
};
typedef struct A * A_id;
typedef struct B * B_id;
A_id make_A()
{
return (A_id)malloc(sizeof(struct A));
}
void destroy_A(A_id * ptr)
{
free(*ptr);
*ptr = 0;
}
B_id make_B()
{
return (B_id)malloc(sizeof(struct B));
}
void destroy_B(B_id * ptr)
{
free(*ptr);
*ptr = 0;
}
void print_a(A_id ptr)
{
printf("print_a\n");
}
void print_b(B_id ptr)
{
printf("print_b\n");
}
#define print(X) _Generic((X),\
A_id : print_a, \
B_id : print_b\
)(X)
int main()
{
A_id aa SCOPE_EXIT(destroy_A) = make_A();
print(aa);
B_id bb SCOPE_EXIT(destroy_B) = make_B();
print(bb);
return 0;
}
Different implementations of functions is one of the key features of polymorphism, so you must use function pointers.
animal.h
typedef struct Animal {
const void (*jump)(struct Animal *self);
} Animal;
pig.h
#include "animal.h"
typedef struct {
Animal animal_interface;
char *name;
} Pig;
Pig *NewPig(char *name);
pig.c
#include <stdio.h>
#include <stdlib.h>
#include "pig.h"
static void PigJump(Animal *_self) {
Pig *self = (Pig *)_self;
printf("%s Pig jump.\n", self->name);
}
Pig *NewPig(char *name) {
Pig *self = (Pig *)malloc(sizeof(Pig));
self->animal_interface.jump = PigJump;
self->name = name;
return self;
}
main.c
#include "pig.h"
int main() {
Animal *a = &(NewPig("Peppa")->animal_interface);
Animal *b = &(NewPig("Daddy")->animal_interface);
a->jump(a);
b->jump(b);
return 0;
}
Output:
Peppa Pig jump.
Daddy Pig jump.
I have successfully achieved polymorphism in C so I felt like sharing my code. I have a struct Pas which "inherits" from struct Zivotinja (Pas means Dog, Zivotinja means Animal BTW).
In both Zivotinja and Pas the first field of the struct is the vTable.
Zivotinja has a vTable of the type ZivotinjaVTable, Pas has a vTable of the type PasVTable. So, we have
typedef struct ZivotinjaVTableStruct{
void (*ispisiPodatkeOZivotinji)(void *zivotinja);
int (*dajGodine) (void *zivotinja);
} ZivotinjaVTable;
typedef struct ZivotinjaStruct{
ZivotinjaVTable *vTable;
int godine;
} Zivotinja;
and we have
typedef struct PasVTableStruct{
void (*ispisiPodatkeOZivotinji)(void *Pas);
int (*dajGodine) (void *Pas);
bool (*daLiJeVlasnikStariji) (void *Pas);
} PasVTable;
typedef struct PasStruct{
PasVTable *vTable;
int godine;
const char* vlasnik;
int godineVlasnika;
} Pas;
Don't worry about the names of the functions, that's not relevant.
Anyway, I then wrote functions for both of these vTables. How did I connect the vTables with the functions that I wrote for them? I created a global struct both for the ZivotinjaVTable and for the PasVTable. I created vTableZivotinjaGlobal and vTablePasGlobal which have function pointers of the functions that I wrote. Then I created functions Pas_new() and Zivotinja_new() which initialize vTable fields to point to these global vTable structs.
Notice the important details in the code above. The important thing is that vTables are the first fields in their structs. That way, when we write
Zivotinja *z = (Zivotinja*) Pas_new(/* init variables */);
z->vTable->someMethod(z);
the compiler knows that vTable is the first field in the Zivotinja struct, so when compiler reads z->vTable, it will go to the memory address to which the first 8 bytes of your struct z point to (or first 4 bytes, if you have a 32bit PC, but that is irrelevant for the point that I am making).
This is how I tricked the computer, since this z pointer is actually pointing to a Pas struct and since PasVTable *vTable is the first field of the Pas struct, after z->vTable we will actually be at the memory address of the pasVTableGlobal, instead of being at the memory address of the zivotinjaVTableGlobal.
Now, another very important detail, someMethod needs to be at the same spot both in the ZivotinjaVTable and in the PasVTable. What I mean is - if someMethod is the 2nd field in the ZivotinjaVTable then it needs to be the second field of the PasVTable. Why?
Because let's say someMethod is the second field of the ZivotinjaVTable, when the compiler reads z->vTable->someMethod(z); computer will take the second 8 bytes in the memory address z->vTable and it will put those 8 bytes into the instruction pointer (or second 4 bytes if you have a 32 bit PC, but again, this is not relevant). Computer "thinks" it is putting the second 8 bytes of the ZivotinjaVTable into the instruction pointer, but in reality it is putting the second 8 bytes of the PasVTable into the instruction pointer.
This is how the trick works, because the function that we want the computer to execute is also the second field (but of the PasVTable, not ZivotinjaVTable), the computer will "think" that it is executing the second function of the ZivotinjaVTable, but in reality it will be executing the second function of the PasVTable.
So, to recapitulate, vTables should be on the same spot in your structs and your structs should have corresponding methods at the same spots in their vTables.
Same goes for other fields of your structs. The second field of the Zivotinja struct matches the second field of the Pas struct, that way when you write
animal_which_is_actually_a_dog->age = 10;
You will trick the compiler in basically the same way as with vTables (you will trick it in the same way that I have described above).
Here is the entire code, in the main function you can write the following
Zivotinja *zivotinja = Zivotinja_new(10);
zivotinja->vTable->ispisiPodatkeOZivotinji(zivotinja);
Zivotinja *pas = Pas_new_sve(5, 50, "Milojko");
pas->vTable->ispisiPodatkeOZivotinji(pas);
int godine = pas->vTable->dajGodine(pas);
printf("The dog which was casted to an animal is %d years old.\n", godine);
Then this is the code for Zivotinja
typedef struct ZivotinjaVTableStruct{
void (*ispisiPodatkeOZivotinji)(void *zivotinja);
int (*dajGodine) (void *zivotinja);
} ZivotinjaVTable;
typedef struct ZivotinjaStruct{
ZivotinjaVTable *vTable;
int godine;
} Zivotinja;
void ispisiPodatkeOOvojZivotinji(Zivotinja* zivotinja){
printf("Ova zivotinja ima %d godina. \n", zivotinja->godine);
}
int dajGodineOveZivotinje(Zivotinja *z){
return z->godine;
}
struct ZivotinjaVTableStruct zivotinjaVTableGlobal = {ispisiPodatkeOOvojZivotinji, dajGodineOveZivotinje};
Zivotinja* Zivotinja_new(int godine){
ZivotinjaVTable *vTable = &zivotinjaVTableGlobal;
Zivotinja *z = (Zivotinja*) malloc(sizeof(Zivotinja));
z->vTable = vTable;
z->godine = godine;
}
And finally, the code for Pas
typedef struct PasVTableStruct{
void (*ispisiPodatkeOZivotinji)(void *Pas);
int (*dajGodine) (void *Pas);
bool (*daLiJeVlasnikStariji) (void *Pas);
} PasVTable;
typedef struct PasStruct{
PasVTable *vTable;
int godine;
const char* vlasnik;
int godineVlasnika;
} Pas;
void ispisiPodatkeOPsu(void *pasVoid){
Pas *pas = (Pas*)pasVoid;
printf("Pas ima %d godina, vlasnik se zove %s, vlasnik ima %d godina. \n", pas->godine, pas->vlasnik, pas->godineVlasnika);
}
int dajGodinePsa(void *pasVoid){
Pas *pas = (Pas*) pasVoid;
return pas->godine;
}
bool daLiJeVlasnikStariji(Pas *pas){
return pas->godineVlasnika >= pas->godine;
}
struct PasVTableStruct pasVTableGlobal = {
ispisiPodatkeOPsu,
dajGodinePsa,
daLiJeVlasnikStariji
};
Pas* Pas_new(int godine){
Pas *z = (Pas*) malloc(sizeof(Pas));
z->vTable = (&pasVTableGlobal);
}
Pas *Pas_new_sve(int godine, int godineVlasnika, char* imeVlasnika){
Pas *pas = (Pas*) malloc(sizeof(Pas));
pas->godine = godine;
pas->godineVlasnika = godineVlasnika;
pas->vlasnik = imeVlasnika;
pas->vTable = &pasVTableGlobal;
}
I have some code with multiple functions very similar to each other to look up an item in a list based on the contents of one field in a structure. The only difference between the functions is the type of the structure that the look up is occurring in. If I could pass in the type, I could remove all the code duplication.
I also noticed that there is some mutex locking happening in these functions as well, so I think I might leave them alone...
If you ensure that the field is placed in the same place in each such structure, you can simply cast a pointer to get at the field. This technique is used in lots of low level system libraries e.g. BSD sockets.
struct person {
int index;
};
struct clown {
int index;
char *hat;
};
/* we're not going to define a firetruck here */
struct firetruck;
struct fireman {
int index;
struct firetruck *truck;
};
int getindexof(struct person *who)
{
return who->index;
}
int main(int argc, char *argv[])
{
struct fireman sam;
/* somehow sam gets initialised */
sam.index = 5;
int index = getindexof((struct person *) &sam);
printf("Sam's index is %d\n", index);
return 0;
}
You lose type safety by doing this, but it's a valuable technique.
[ I have now actually tested the above code and fixed the various minor errors. It's much easier when you have a compiler. ]
Since structures are nothing more than predefined blocks of memory, you can do this. You could pass a void * to the structure, and an integer or something to define the type.
From there, the safest thing to do would be to recast the void * into a pointer of the appropriate type before accessing the data.
You'll need to be very, very careful, as you lose type-safety when you cast to a void * and you can likely end up with a difficult to debug runtime error when doing something like this.
I think you should look at the C standard functions qsort() and bsearch() for inspiration. These are general purpose code to sort arrays and to search for data in a pre-sorted array. They work on any type of data structure - but you pass them a pointer to a helper function that does the comparisons. The helper function knows the details of the structure, and therefore does the comparison correctly.
In fact, since you are wanting to do searches, it may be that all you need is bsearch(), though if you are building the data structures on the fly, you may decide you need a different structure than a sorted list. (You can use sorted lists -- it just tends to slow things down compared with, say, a heap. However, you'd need a general heap_search() function, and a heap_insert() function, to do the job properly, and such functions are not standardized in C. Searching the web shows such functions exist - not by that name; just do not try "c heap search" since it is assumed you meant "cheap search" and you get tons of junk!)
If the ID field you test is part of a common initial sequence of fields shared by all the structs, then using a union guarantees that the access will work:
#include <stdio.h>
typedef struct
{
int id;
int junk1;
} Foo;
typedef struct
{
int id;
long junk2;
} Bar;
typedef union
{
struct
{
int id;
} common;
Foo foo;
Bar bar;
} U;
int matches(const U *candidate, int wanted)
{
return candidate->common.id == wanted;
}
int main(void)
{
Foo f = { 23, 0 };
Bar b = { 42, 0 };
U fu;
U bu;
fu.foo = f;
bu.bar = b;
puts(matches(&fu, 23) ? "true" : "false");
puts(matches(&bu, 42) ? "true" : "false");
return 0;
}
If you're unlucky, and the field appears at different offsets in the various structs, you can add an offset parameter to your function. Then, offsetof and a wrapper macro simulate what the OP asked for - passing the type of struct at the call site:
#include <stddef.h>
#include <stdio.h>
typedef struct
{
int id;
int junk1;
} Foo;
typedef struct
{
int junk2;
int id;
} Bar;
int matches(const void* candidate, size_t idOffset, int wanted)
{
return *(int*)((const unsigned char*)candidate + idOffset) == wanted;
}
#define MATCHES(type, candidate, wanted) matches(candidate, offsetof(type, id), wanted)
int main(void)
{
Foo f = { 23, 0 };
Bar b = { 0, 42 };
puts(MATCHES(Foo, &f, 23) ? "true" : "false");
puts(MATCHES(Bar, &b, 42) ? "true" : "false");
return 0;
}
One way to do this is to have a type field as the first byte of the structure. Your receiving function looks at this byte and then casts the pointer to the correct type based on what it discovers. Another approach is to pass the type information as a separate parameter to each function that needs it.
You can do this with a parameterized macro but most coding policies will frown on that.
#include
#define getfield(s, name) ((s).name)
typedef struct{
int x;
}Bob;
typedef struct{
int y;
}Fred;
int main(int argc, char**argv){
Bob b;
b.x=6;
Fred f;
f.y=7;
printf("%d, %d\n", getfield(b, x), getfield(f, y));
}
Short answer: no. You can, however, create your own method for doing so, i.e. providing a specification for how to create such a struct. However, it's generally not necessary and is not worth the effort; just pass by reference. (callFuncWithInputThenOutput(input, &struct.output);)
I'm a little rusty on c, but try using a void* pointer as the variable type in the function parameter. Then pass the address of the structure to the function, and then use it he way that you would.
void foo(void* obj);
void main()
{
struct bla obj;
...
foo(&obj);
...
}
void foo(void* obj)
{
printf(obj -> x, "%s")
}