Object oriented C programming - equivalent of 'this' keyword? - c

I'm experimenting with OOP in C, based off of this answer. I came across something I can't quite get around. Take this example:
struct foo {
int val;
int (*bar)(struct foo, int);
}
int foo_bar(struct foo mod, int val)
{
mod.val = val;
}
int main(void)
{
struct foo foo;
foo.bar = foo_bar;
foo.bar(foo, 8);
}
I think it would be much simpler and clearer if there was a way to use the this keyword in C:
struct foo {
int val;
int (*bar)(struct foo, int);
}
int foo_bar(int val)
{
this.val = val;
}
int main(void)
{
struct foo foo;
foo.bar = foo_bar;
foo.bar(8);
}
It sounds impossible, but there may be some workaround out there, a bit like OOP in C itself. Is there any way to achieve the functionality of the this keyword in Object-Oriented C?

No. this keyword in C++ is a reference to the object at hand, and is actually explicitly passed to the member functions at the ABI level. Explicitly passing a pointer to the object (as the first parameter) in functions is the best equivalent in C. Note that this means
struct foo {
int value;
int (*func)(struct foo *, int);
};
void foo_bar(struct foo *f, int value)
{
f->value = value;
}
i.e. the pointer to the object is passed as the first parameter, rather than the structure itself. This makes it explicit that the object is passed by reference, and makes understanding and maintaining such code easier.
It is not sane to expect features seen in one programming language to be valid in some other programming language, even if the two are related somehow.
You see, each programming language has their own approach to problem solving, their own paradigm. Because there is no universal best paradigm possible, problems are best solved using a programming language that has the most applicable/efficient/useful paradigm. For example, you don't write a C++ program to expedite common command-line tasks; you use a shell script or other simple scripting language instead.
As a programmer, having the ability to switch from one programming language paradigm to another means you have the ability to look at a problem from different viewpoints. Looking at current software projects, the most robust, vital, and efficient ones are written by programmers who have that ability.
This is why I stated, above, that it is not sane to expect the features or paradigm of one programming language to be portable to others. You should not do that, because it is equivalent to having a single tool, and looking at all problems as if your tool at hand is the only possible tool in solving them. (If all you have is a hammer, all problems start looking like nails.) Learning, and especially learning to accept, the different paradigms in different programming languages, makes for a better programmer, better problem-solver.

Related

Getters and setters in pure C?

Can I use getters and setters in pure C instead of using extern variables?
First of all, don't listen to anyone saying "there is no object-orientation in language x" because they have truly not understood that OO is a program design method, completely apart from language syntax.
Some languages have elegant ways to implement OO, some have not. Yet it is possible to write an object-oriented program in any language, for example in C. Similarly, your program will not automagically get a proper OO design just because you wrote it in Java, or because you used certain language keywords.
The way you implement private encapsulation in C is a bit more crude than in languages with OO support, but it does like this:
// module.h
void set_x (int n);
int get_x (void);
// module.c
static int x; // private variable
void set_x (int n)
{
x = n;
}
int get_x (void)
{
return x;
}
// main.c
#include "module.h"
int main (void)
{
set_x(5);
printf("%d", get_x());
}
Can call it "class" or "ADT" or "code module" as you prefer.
This is how every reasonable C program out there is written. And has been written for the past 30-40 years or so, as long as program design has existed. If you say there are no setters/getters in a C program, then that is because you have no experience of using C.
Yes, it's very much possible and sometimes even useful. C supports opaque types:
struct Context;
C code compiled with only this declaration in scope can not access any hypothetical members of the struct, and can't use value of type Context either. But it can still handle pointers to Context values, so functions like these are possible:
Context *make_context(...);
int context_get_foo(Context *);
void context_set_foo(Context *, int);
This pattern insulates the client C code from any changes to the size or internal layout of Context. Note that this is a stronger guarantee than simply declaring but not documenting the members: Even if the programmers duly ignore the undocumented members, by-value use of the struct is permitted (and will certainly slip in), and now the code has to be recompiled when the size changes. In other words, opaque types only handled through pointers give greater ABI stability.
Another approach is by using a global variable and inline functions:
// module.h
inline void set_x (int n) {extern int x; x = n;}
inline int get_x (void) {extern int x; return x;}
// module.c
int x; // global variable
// main.c
#include "module.h"
int main (void)
{
set_x(5);
printf("%d", get_x());
}
It has two advantages:
Getters and setters become easily inlineable
It becomes clear to the compiler that getters have no side effects, which allows further optimizations and produces no warnings in cases like this one:
// warning: compound statement with side effects
if(get_x() || get_y())
Of course, a "dedicated" (read: dumb) programmer can always write extern int x; in their code and use the variable directly. On the other hand, a "dedicated" programmer can also easily remove the static keyword and use it anyway...

C function composition [duplicate]

Is there a "proper" way to implement higher order functions in C.
I'm mostly curious about things like portability and syntax correctness here and if there are more than one ways what the merits and flaws are.
Edit:
The reason I want to know how to create higher order functions are that I have written a system to convert PyObject lists (which you get when calling python scripts) into a list of C structures containing the same data but organized in a way not dependant on the python.h libraries. So my plan is to have a function which iterates through a pythonic list and calls a function on each item in the list and places the result in a list which it then returns.
So this is basically my plan:
typedef gpointer (converter_func_type)(PyObject *)
gpointer converter_function(PyObject *obj)
{
// do som stuff and return a struct cast into a gpointer (which is a void *)
}
GList *pylist_to_clist(PyObject *obj, converter_func_type f)
{
GList *some_glist;
for each item in obj
{
some_glist = g_list_append(some_glist, f(item));
}
return some_glist;
}
void some_function_that_executes_a_python_script(void)
{
PyObject *result = python stuff that returns a list;
GList *clist = pylist_to_clist(result, converter_function);
}
And to clearify the question: I want to know how to do this in safer and more correct C. I would really like to keep the higher order function style but if that is frowned upon I greatly appreciate ways to do this some other way.
Technically, higher-order functions are just functions that take or return functions. So things like qsort are already higher-order.
If you mean something more like the lambda functions found in functional languages (which is where higher order functions really become useful), those are quite a bit harder and can't be done naturally in current standard C. They're just not part of the language. Apple's blocks extension is the best candidate. It only works in GCC (and LLVM's C compiler), but they are really useful. Hopefully something like that will catch on. Here's a few relevant resources:
Apple's documentation on the feature (references some Apple-specific technologies and also addresses Objective-C, but the core block stuff is part of their extensionto C)
Here's a good intro on blocks
Cocoa for Scientists' overview of C blocks
The big problem with implementing higher-order functions in C is that to do anything non-trivial you need closures, which are function pointers augmented with data structures containing local variables they have access to. Since the whole idea behind closures is to capture local variables and pass those along with the function pointer, it's hard to do without compiler support. And even with compiler support it's hard to do without garbage collection because variables can exist outside of their scope, making it hard to figure out when to free them.
This is an answer to the question: how to compose functions in C, which is redirected here.
You can create a data structure to implement a list data type.
that structure can contain function pointers.
#include<stdlib.h>
#include<malloc.h>
typedef (*fun)();
typedef struct funList { fun car; struct funList *cdr;} *funList;
const funList nil = NULL;
int null(funList fs){ return nil==fs; }
fun car(funList fs)
{
if(!null(fs)) return fs->car;
else
{
fprintf(stderr,"error:can't car(nil) line:%d\n",__LINE__);
exit(1);
}
}
funList cdr(funList ls)
{ if(!null(ls)) return ls->cdr;
else
{
fprintf(stderr,"error:can't cdr(nil) line:%d\n",__LINE__);
exit(1);
}
}
funList cons(fun f, funList fs)
{ funList ls;
ls=(funList) malloc(sizeof(struct funList));
if(NULL==ls)
{
fprintf(stderr,"error:can't alloc mem for cons(...) line:%d\n",__LINE__);
exit(1);
}
ls->car=f;
ls->cdr=fs;
return ls;
}
we can write a function comp which applies a list of functions:
type_2 comp(funList fs, type_1 x)
{
return (null(fs)) ? x : car(fs)(comp(cdr(fs),x));
}
An example of how it works. We use (f g h) as a short notation for cons(f,cons(g,cons(h,nil))), which is applied to a given argument x:
comp((f g h),x)
=
f(comp((g h),x))
=
f(g(comp((h),x)))
=
f(g(h(comp(nil,x))))
=
f(g(h(x)))
if you had used the polymorphic list type in a typed language like SML or Haskell the type of comp should be:
comp :: ([a -> a],a) -> a
because in that context all the members in a list have the same type.
C can be more flexible in this sense. Maybe something like
typedef void (*fun)();
or
typedef (*fun)();
you should see what the C manual say about this. And be sure that all contiguous functions have compatible types.
The functions to compose should be pure, i.e. without side effects nor free variables.
In straight c, this is really only done through function pointers, which are both a pain and not meant for this type of thing (which is partially why they are a pain). Blocks (or closures, according to non-apple) are fantastic for this, though. They compile in gcc-4.x or something, and icc something, but regardless thats what you're looking for. Unfortunately, I can't seem to find any good tutorials online, but suffice to say it works something like this:
void iterate(char *str, int count, (^block)(str *)){
for(int i = 0; i < count; i++){
block(list[i]);
}
}
main() {
char str[20];
iterate(str, 20, ^(char c){
printf("%c ", c);
});
int accum = 0;
iterate(someList, 20, ^(char c){
accum += c;
iterate(str, 20, ^(char c){
printf("%c ", c);
});
});
}
obviously this code is pointless, but it it prints each character of a string (str) with a space in between it, then adds all of the characters together into accum, and every time it does it prints out the list of characters again.
Hope this helps. By the way, blocks are very visible in Mac OS X Snow Leopard api-s, and I believe are in the forthcoming C++0x standard, so they're not really that unusual.
If you're keen on doing this in plain C, you need to remember to include the option to pass in a context pointer from the caller of the functor (the higher-order function) to the function passed in. This lets you simulate enough of a closure that you can make things work easily enough. What that pointer points to... well, that's up to you, but it should be a void* in the functor's API (or one of the many aliases for it, such as gpointer in the GLib world or ClientData in the Tcl C API).
[EDIT]: To use/adapt your example:
typedef gpointer (converter_func_type)(gpointer,PyObject *)
gpointer converter_function(gpointer context_ptr,PyObject *obj)
{
int *number_of_calls_ptr = context_ptr;
*number_of_calls_ptr++;
// do som stuff and return a struct cast into a gpointer (which is a void *)
}
GList *pylist_to_clist(PyObject *obj, converter_func_type f, gpointer context_ptr)
{
GList *some_glist;
for each item in obj
{
some_glist = g_list_append(some_glist, f(context_ptr,item));
}
return some_glist;
}
void some_function_that_executes_a_python_script(void)
{
int number_of_calls = 0;
PyObject *result = python stuff that returns a list;
GList *clist = pylist_to_clist(result, converter_function, &number_of_calls);
// Now number_of_calls has how often converter_function was called...
}
This is a trivial example of how to do it, but it should show you the way.
Practically any interesting higher order function application requires closures, which in C entails the laborous and error-prone routine of manually defining and filling struct function arguments.
It's very difficult to do in straight C. It's more possible in C++ (see functors tutorial or Boost's bind and function libraries). Finally, C++0x adds native support for lambda functions, which takes care for you of capturing in closure all of the variables that your funcion depends on.
If you want to create higher order functions, don't use C. There are C solutions to your problem. They may not be elegant, or they may be more elegant that you realize.
[Edit] I suggested that the only way to achieve this was to use a scripting language. Others have called me out on it. So, I'm replacing that suggestion with this: [/Edit]
What are you trying to achieve? If you want to mimic closures, use a language that supports them (you can tie into Ruby, lua, javascript, etc through libraries). If you want to use callbacks, function pointers are ok. Function pointers combine the most dangerous areas of C (pointers and the weak type system), so be careful. Function pointer declarations are not fun to read, either.
You find some C libraries using function pointers because they have to. If you're writing a library, maybe you need to use them, too. If you're just using them within your own code, you're probably not thinking in C. You're thinking in lisp or scheme or ruby or ... and trying to write it in C. Learn the C way.

Which way is better for creating type-agnostic structures in C?

I'm trying to write some generic structures. Essentially, what I need for my purpose is C++ templates, but since I'm writing in C, templates are out of consideration. Currently I'm considering 2 ways of achieving what I want.
Method 1: use the preprocessor. Like so:
#define DEFINE_PAIR(T) typedef struct Pair_##T{ \
T x; \
T y; \
} Pair_##T
DEFINE_PAIR(int);
int main(){
Pair_int p;
return 0;
}
An obvious downside to it is that you have to invoke the macro before using the type. Probably there are more disadvantages, which I hope you will point out.
Method 2: just use void-pointers, like so:
typedef struct Pair{
void* x;
void* y;
} Pair;
Obviously, this approach is not type safe (I could easily pass a pair of strings to a function expecting a pair of doubles), plus the code doing deallocation gets a lot messier with this approach.
I would like to hear your thoughts on this. Which of the two methods is better/worse and why? Is there any other method I could use to write generic structures in C?
Thanks.
If you only plan on using primitive data types, then your original macro-based solution seems nifty enough. However, when you start storing pairs of pointers to opaque data types with complex structures underneath that are meant to be used by passing pointers between functions, such as:
complex_structure_type *object = complex_structure_type_init();
complex_structure_type_set_title(object, "Whatever");
complex_structure_type_free(object);
then you have to
typedef complex_structure_type *complex_structure_type_ptr;
in order to
DEFINE_PAIR(complex_structure_type_ptr);
so you can
Pair_complex_structure_type_ptr p;
and then
p.x = object;
But that's only a little bit more work, so if you feel it works for you, go for it. You might even put together your own preprocessor that goes through the code, pulls out anything like Pair_whatever, and then adds DEFINE_PAIR(whatever) for the C preprocessor. Anyway, it's definitely a neat idea that you've presented here.
Personally, I would just use void pointers and forget about strong type safety. C just doesn't have the same type safety machinery as other languages, and the more opportunities you give yourself to forget something, the more bugs you'll accidentally create.
Good luck!
Noting that templates in c++ provide a language for writing code, you might simple consider doing code generation with some tool more powerful than the c-preprocessor.
Now that does add another step to you build, and makes you build depend on another toll (unless you care to write your own generator in c...), but it may provide the flexibility and type-safety you desire.
This is almost the same, but it's a bit more nimble:
#define PAIR_T(TYPE) \
struct { \
TYPE x; \
TYPE y; \
}
typedef PAIR_T(int) int_pair;
typedef PAIR_T(const char *) string_pair;
int main(void)
{
int_pair p = {1, 1};
string_pair sp = {"a", "b"};
}

How to define constructor in C

How can one create a Haskell/C++ style constructor in C? Also, once I have this new object how can I define operations in it (such as LinkedList/Tree)?
C has no language support for objected-oriented concepts such as constructors.
You could manually implement this, along the lines of:
typedef struct
{
int field1;
int field2;
} MyObject;
MyObject *MyObject_new(int field1, int field2)
{
MyObject *p = malloc(sizeof(*p));
if (p != NULL)
{
// "Initialise" fields
p->field1 = field1;
p->field2 = field2;
}
return p;
}
void MyObject_delete(MyObject *p)
{
// Free other resources here too
if (p != NULL)
{
free(p);
}
}
void MyObject_doSomethingInteresting(const MyObject *p)
{
printf("How interesting: %d\n", p->field1 * p->field2);
}
If you want to get really advanced, you can use hideously-complex macros and function pointers to emulate polymorphism and all sorts (at the expense of type-safety); see this book.
See also this question.
See also this FAQ answer if you're interested in compiling object-oriented C++ into C.
I suspect that #Oli Charlesworth's answer is what you really wanted here, but for completeness' sake, if you really want Haskell-style constructors:
Nullary data constructors like True and False can be represented easily by regular enum types. To stay accurate to Haskell you'll want to pretend that you can't treat them as integer values, unless you're also pretending that your Haskell type is an instance of Enum.
Data constructors for product types like (True, "abc") can be represented by functions that take appropriate arguments and return an appropriate struct. Haskell's "record syntax" can be imitated using a struct because C-style structs are already being imitated by Haskell's record syntax. Yay, recursion!
Data constructors for sum types like Nothing and Just 5 can be imitated by a union. To stay accurate to Haskell you'll need to "tag" the union to distinguish the cases safely, such as using a struct and an enum. Think of the | in Haskell's data declarations as indicating an untagged union, with the individual constructors like Nothing and Just being nullary constructors required to be the first element of a product type forming each branch. This is slightly more complicated to implement than you'd think after realizing that it's simpler than it sounds at first.
Type constructors don't really translate well to C. You might be able to fake it badly, if you want to, using macros and such. But you probably don't want to, so stick to monomorphic code.
If you want to put any of the above into practice in actual code, well... good luck and godspeed.

Higher order functions in C

Is there a "proper" way to implement higher order functions in C.
I'm mostly curious about things like portability and syntax correctness here and if there are more than one ways what the merits and flaws are.
Edit:
The reason I want to know how to create higher order functions are that I have written a system to convert PyObject lists (which you get when calling python scripts) into a list of C structures containing the same data but organized in a way not dependant on the python.h libraries. So my plan is to have a function which iterates through a pythonic list and calls a function on each item in the list and places the result in a list which it then returns.
So this is basically my plan:
typedef gpointer (converter_func_type)(PyObject *)
gpointer converter_function(PyObject *obj)
{
// do som stuff and return a struct cast into a gpointer (which is a void *)
}
GList *pylist_to_clist(PyObject *obj, converter_func_type f)
{
GList *some_glist;
for each item in obj
{
some_glist = g_list_append(some_glist, f(item));
}
return some_glist;
}
void some_function_that_executes_a_python_script(void)
{
PyObject *result = python stuff that returns a list;
GList *clist = pylist_to_clist(result, converter_function);
}
And to clearify the question: I want to know how to do this in safer and more correct C. I would really like to keep the higher order function style but if that is frowned upon I greatly appreciate ways to do this some other way.
Technically, higher-order functions are just functions that take or return functions. So things like qsort are already higher-order.
If you mean something more like the lambda functions found in functional languages (which is where higher order functions really become useful), those are quite a bit harder and can't be done naturally in current standard C. They're just not part of the language. Apple's blocks extension is the best candidate. It only works in GCC (and LLVM's C compiler), but they are really useful. Hopefully something like that will catch on. Here's a few relevant resources:
Apple's documentation on the feature (references some Apple-specific technologies and also addresses Objective-C, but the core block stuff is part of their extensionto C)
Here's a good intro on blocks
Cocoa for Scientists' overview of C blocks
The big problem with implementing higher-order functions in C is that to do anything non-trivial you need closures, which are function pointers augmented with data structures containing local variables they have access to. Since the whole idea behind closures is to capture local variables and pass those along with the function pointer, it's hard to do without compiler support. And even with compiler support it's hard to do without garbage collection because variables can exist outside of their scope, making it hard to figure out when to free them.
This is an answer to the question: how to compose functions in C, which is redirected here.
You can create a data structure to implement a list data type.
that structure can contain function pointers.
#include<stdlib.h>
#include<malloc.h>
typedef (*fun)();
typedef struct funList { fun car; struct funList *cdr;} *funList;
const funList nil = NULL;
int null(funList fs){ return nil==fs; }
fun car(funList fs)
{
if(!null(fs)) return fs->car;
else
{
fprintf(stderr,"error:can't car(nil) line:%d\n",__LINE__);
exit(1);
}
}
funList cdr(funList ls)
{ if(!null(ls)) return ls->cdr;
else
{
fprintf(stderr,"error:can't cdr(nil) line:%d\n",__LINE__);
exit(1);
}
}
funList cons(fun f, funList fs)
{ funList ls;
ls=(funList) malloc(sizeof(struct funList));
if(NULL==ls)
{
fprintf(stderr,"error:can't alloc mem for cons(...) line:%d\n",__LINE__);
exit(1);
}
ls->car=f;
ls->cdr=fs;
return ls;
}
we can write a function comp which applies a list of functions:
type_2 comp(funList fs, type_1 x)
{
return (null(fs)) ? x : car(fs)(comp(cdr(fs),x));
}
An example of how it works. We use (f g h) as a short notation for cons(f,cons(g,cons(h,nil))), which is applied to a given argument x:
comp((f g h),x)
=
f(comp((g h),x))
=
f(g(comp((h),x)))
=
f(g(h(comp(nil,x))))
=
f(g(h(x)))
if you had used the polymorphic list type in a typed language like SML or Haskell the type of comp should be:
comp :: ([a -> a],a) -> a
because in that context all the members in a list have the same type.
C can be more flexible in this sense. Maybe something like
typedef void (*fun)();
or
typedef (*fun)();
you should see what the C manual say about this. And be sure that all contiguous functions have compatible types.
The functions to compose should be pure, i.e. without side effects nor free variables.
In straight c, this is really only done through function pointers, which are both a pain and not meant for this type of thing (which is partially why they are a pain). Blocks (or closures, according to non-apple) are fantastic for this, though. They compile in gcc-4.x or something, and icc something, but regardless thats what you're looking for. Unfortunately, I can't seem to find any good tutorials online, but suffice to say it works something like this:
void iterate(char *str, int count, (^block)(str *)){
for(int i = 0; i < count; i++){
block(list[i]);
}
}
main() {
char str[20];
iterate(str, 20, ^(char c){
printf("%c ", c);
});
int accum = 0;
iterate(someList, 20, ^(char c){
accum += c;
iterate(str, 20, ^(char c){
printf("%c ", c);
});
});
}
obviously this code is pointless, but it it prints each character of a string (str) with a space in between it, then adds all of the characters together into accum, and every time it does it prints out the list of characters again.
Hope this helps. By the way, blocks are very visible in Mac OS X Snow Leopard api-s, and I believe are in the forthcoming C++0x standard, so they're not really that unusual.
If you're keen on doing this in plain C, you need to remember to include the option to pass in a context pointer from the caller of the functor (the higher-order function) to the function passed in. This lets you simulate enough of a closure that you can make things work easily enough. What that pointer points to... well, that's up to you, but it should be a void* in the functor's API (or one of the many aliases for it, such as gpointer in the GLib world or ClientData in the Tcl C API).
[EDIT]: To use/adapt your example:
typedef gpointer (converter_func_type)(gpointer,PyObject *)
gpointer converter_function(gpointer context_ptr,PyObject *obj)
{
int *number_of_calls_ptr = context_ptr;
*number_of_calls_ptr++;
// do som stuff and return a struct cast into a gpointer (which is a void *)
}
GList *pylist_to_clist(PyObject *obj, converter_func_type f, gpointer context_ptr)
{
GList *some_glist;
for each item in obj
{
some_glist = g_list_append(some_glist, f(context_ptr,item));
}
return some_glist;
}
void some_function_that_executes_a_python_script(void)
{
int number_of_calls = 0;
PyObject *result = python stuff that returns a list;
GList *clist = pylist_to_clist(result, converter_function, &number_of_calls);
// Now number_of_calls has how often converter_function was called...
}
This is a trivial example of how to do it, but it should show you the way.
Practically any interesting higher order function application requires closures, which in C entails the laborous and error-prone routine of manually defining and filling struct function arguments.
It's very difficult to do in straight C. It's more possible in C++ (see functors tutorial or Boost's bind and function libraries). Finally, C++0x adds native support for lambda functions, which takes care for you of capturing in closure all of the variables that your funcion depends on.
If you want to create higher order functions, don't use C. There are C solutions to your problem. They may not be elegant, or they may be more elegant that you realize.
[Edit] I suggested that the only way to achieve this was to use a scripting language. Others have called me out on it. So, I'm replacing that suggestion with this: [/Edit]
What are you trying to achieve? If you want to mimic closures, use a language that supports them (you can tie into Ruby, lua, javascript, etc through libraries). If you want to use callbacks, function pointers are ok. Function pointers combine the most dangerous areas of C (pointers and the weak type system), so be careful. Function pointer declarations are not fun to read, either.
You find some C libraries using function pointers because they have to. If you're writing a library, maybe you need to use them, too. If you're just using them within your own code, you're probably not thinking in C. You're thinking in lisp or scheme or ruby or ... and trying to write it in C. Learn the C way.

Resources