"this" pointer in C (not C++)

I'm trying to create a stack in C for fun, and came up with the idea of using struct to represent the stack. Then I add function pointers to the struct for push() and pop() operations.

So far all is good it seems, but, for the implementation of the push() and pop() functions I need to refer to *this somehow. How can that (can it?) be done?

This is my struct

struct Stack {
    int *data;
    int current_size;
    int max_size;
    int (*push)(int);
    int (*pop)();

And as an example here's push

int push(int val) {
    if(current_size == max_size -1)
            return 0;

    data[current_size] = val;

    return 1;

As you can imagine, the compiler has no idea what current_size is, as it would expect something like stack->current_size.

Is this possible to overcome somehow?

There's no implicit this in C. Make it explicit:

int push(Stack* self, int val) {
    if(self->current_size == self->max_size - 1)
            return 0;

    self->data[self->current_size] = val;

    return 1;

You will of course have to pass the pointer to the struct into every call to push and similar methods.

This is essentially what the C++ compiler is doing for you when you define Stack as a class and push et al as methods.

The typical approach in C is to have functions expect this as the first parameter.

int push(Stack *self, int val) 
  if (self->current_size == self->max_size -1) return 0;
  self->data[self->current_size++] = val;
  return 1;

This has the added benefit that, unless you need polymorphism, you don't need to put the functions in the stack, because you could just call push(stack, 10) instead of stack->push(stack,10).

C doesn't work like that. It's not an object oriented language. Functions that manipulate data structures need to take a pointer to the structure as an argument.

Your function pointers aren't methods so they don't have any information about the calling object. The only way to do what you want is to either pass in a pointer to the object, or make that pointer global (the latter is not recommended).

Since your are going to have only one Stack structure (that you named stack, apparently), you could define it as a global variable. This would allow pop/push to refer to the stack variable directly.

You would do something like:

stack.current_size += 4;

or use the -> operator if you decide to declare stack as a memory pointer to Stack.

  • what's the point of function pointers in your stack struct?
  • To try to get an answer to if it's at all possible to call a stack of this type like this: stack->push(10);. Now, if the answer is not given here I can be pretty confident that it's indeed impossible.
  • That's the idea, but using this as a variable is awkward, if someone ever tries to include your C in a C++ program.
  • I could do this, but then there is no point in having the functions as pointers in the struct. If possible I'd like to just call push(int val), even if things gets ugly. If the answer is that it's impossible to do, that is a satisfying answer as well.
  • There are many reasons other than this why including C code in a C++ source file is not valid and could lead to major bugs. Just don't do it. If this makes sense as a variable name (as it does here), use it.
  • @foo: There's still a point of putting the function pointers in the struct. You should never declare external functions with such generic names as push and pop, especially if the code might eventually be part of a library. So you'd either need to name them something like foo_push and foo_pop, or you could hide them as static in the implementation file for the stack and have foo_allocstack return a stack object with the function pointers set to point to these static functions. The latter solution has more overhead, but it could be useful.
  • Thanks. That was my first approach, but I wanted to have some fun with function pointers and wanted to see how far it was possible to get C to get a C++ behavior. The purpose of this is to educate myself and experiment, nothing serious. I agree that using push(stack, 10) is the most sensible thing to do in C.
  • You just locked your car with the keys inside.
  • That seems obvious. Did not thing about that, must try it out. Thanks
  • I'm wondering if different users on this site see questions before others. I don't see how a question like this can get four answers in less than one minute.
  • @foo - with this solution you still have the exact same problem - the functions that push and pop point to don't know anything about the calling object.
  • There's acually no good reason to have the Stack * as a member of the struct. The struct address needs to be passed into the functions that are called off the pointers.