"this" pointer in C (not C++)
Solution 1
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.
Solution 2
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)
.
Solution 3
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.
Related videos on Youtube
foo
Updated on July 09, 2022Comments
-
foo almost 2 years
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 likestack->current_size
.Is this possible to overcome somehow?
-
Nyan over 13 yearswhat's the point of function pointers in your stack struct?
-
foo over 13 yearsTo 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.
-
-
Victor Nicollet over 13 yearsThat's the idea, but using
this
as a variable is awkward, if someone ever tries to include your C in a C++ program. -
Victor Nicollet over 13 yearsYou just locked your car with the keys inside.
-
foo over 13 yearsThat seems obvious. Did not thing about that, must try it out. Thanks
-
ThomasMcLeod over 13 yearsI'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.
-
Niki Yoshiuchi over 13 years@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.
-
ThomasMcLeod over 13 yearsThere'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.
-
foo over 13 yearsI 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. -
ThomasMcLeod over 13 yearsStoring the pointer in the struct doesn't help because that data, the struct address, is available in the scope in which you call the function pointers.
-
foo over 13 years@Niki - I see, yes that makes sense.
-
foo over 13 years@Thomas - The answers did indeed come within a minute after I posted the question. This place is great that way.
-
R.. GitHub STOP HELPING ICE over 13 yearsThere 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. Ifthis
makes sense as a variable name (as it does here), use it. -
R.. GitHub STOP HELPING ICE over 13 years@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
andpop
, especially if the code might eventually be part of a library. So you'd either need to name them something likefoo_push
andfoo_pop
, or you could hide them asstatic
in the implementation file for the stack and havefoo_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.