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?
27 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.
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.
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); 1Your 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.
8Since 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.