"This" Pointer in C (Not C++)

"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;
    current_size++;

    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?

2

7 Answers

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;
    (self->current_size)++;

    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.

4

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).

1

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.

In header file you can declare static this variable

static struct Stack *this;

And then in push method you can use this variable

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

    this->data[this->current_size] = val;
    (this->current_size)++;

    return 1;
}

The caveat is you have to manually set this variable through some method before you want to invoke other methods, eg:

struct Stack {
    struct Stack (*_this)(struct Stack *); // <-- we create this method
    int *data;
    int current_size;
    int max_size;
    int (*push)(int);
    int (*pop)();
};

And then we can implement _this method as

static struct Stack *_this(struct Stack *that)
{
    retrun this = that;
}

The example:

struct Stack stack1, stack2;

... some initialization ...

stack1->_this(&stack1)->push(0);
stack1->push(1);
stack1->push(2);

stack2->_this(&stack2);
stack2->push(10);
stack2->push(20);
1

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).

Obviously you can have a Stack * member in the struct and then just initialize it with the address of the struct before you use the function pointers. Then make the Stack * a parameter on the function pointers.

8

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Alexander Ross
Author

Alexander Ross

Alexander Ross has covered the video game industry for a decade, writing deep dives on game design, esports tournaments, VR developments, and gaming culture.