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

32,246

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.

Share:
32,246

Related videos on Youtube

foo
Author by

foo

Updated on July 09, 2022

Comments

  • foo
    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 like stack->current_size.

    Is this possible to overcome somehow?

    • Nyan
      Nyan over 13 years
      what's the point of function pointers in your stack struct?
    • foo
      foo over 13 years
      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.
  • Victor Nicollet
    Victor Nicollet over 13 years
    That'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
    Victor Nicollet over 13 years
    You just locked your car with the keys inside.
  • foo
    foo over 13 years
    That seems obvious. Did not thing about that, must try it out. Thanks
  • ThomasMcLeod
    ThomasMcLeod over 13 years
    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.
  • Niki Yoshiuchi
    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
    ThomasMcLeod over 13 years
    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.
  • foo
    foo over 13 years
    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.
  • ThomasMcLeod
    ThomasMcLeod over 13 years
    Storing 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
    foo over 13 years
    @Niki - I see, yes that makes sense.
  • foo
    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
    R.. GitHub STOP HELPING ICE over 13 years
    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.
  • R.. GitHub STOP HELPING ICE
    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 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.

Related