-4

I need to do that in C.

I have a typedef struct with property x, and I will create many structs from the typedef struct. How can I refer to a given parent struct from the property. In reality, this x is a function, and the function needs to know what the other property, y, is.

How to do this in Javascript is

this.super

My code

#define NOTHING

typedef struct $ {
    int (*x)(void);
    int Y NOTHING;
} $;
int AddOneToParentY (void) {
    //return This.super.Y +1; but in c instead of js
};

$ struct1 = {
    .X = AddOneToParentY,
    .Y = 3 NOTHING
};

$ struct2 = {
    .X = AddOneToParentY,
    .Y = 32 NOTHING
};

//When I call struct2.AddOneToParentY I should get 33

How to do this? Maybe something with POUND define macros?

3 Answers3

2

I think you're asking for an analogue of the this pointer of C++ member functions (equivalently, the this reference of Java instance methods). But C does not have an analogue of member functions or instance methods. More generally, it does not have built-in features catering specifically to OOP -- that's why C++ was forked from C, after all.

A C structure can have a member that is a pointer to a function, but calling that function through such a pointer is not different from calling it directly, or calling it through a different pointer to it. There is no distinction, and therefore no way to tell which pointer was used to identify the function, much less what data may be related to it or stored nearby.

The usual C alternative is essentially to provide an explicit this pointer to functions that want one (though it may go by any name you like), and to pass it explicitly. That may, additionally, reduce or eliminate the usefulness of storing pointers to it in the structure. For example:

typedef struct {
    double x, y, radius;
} circle;

double computeArea(circle *c) {
    return c->radius * c->radius * 3.14159;
}

void moveTo(circle *c, double new_x, double new_y) {
    c->x = new_x;
    c->y = new_y;
}

int main(void) {
    circle a_circle = { .x = 1, .y = 1, .radius = 2 };

    printf("The area is %f\n", computeArea(&a_circle));
}
John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • For what I am trying, do you think I should switch to c++? –  Jul 08 '19 at 19:33
  • 1
    @16squared, I have no basis on which to advise you about what language to use. The idiom I have presented is relatively common in C, and it works just fine. If you want to build class hierarchies and rely heavily on inheritance and polymorphism, however, then C is an odd language choice. – John Bollinger Jul 08 '19 at 19:37
2

C doesn't have the concept of classes and inheritance, so there's nothing built into the language to do something like this.

You need to declare your function to take a pointer to the struct you want to modify and work on that. Also, $ is not a good name for a type. You should give it a textual name instead.

typedef struct mystruct {
    int Y;
} mystruct;

int AddOneToParentY (mystruct *s) {
    return s->Y + 1;
};

mystruct struct1 = {
    .Y = 3
};

mystruct struct2 = {
    .Y = 32
};


...

printf("result=%d\n", AddOneToParentY(&struct1);
dbush
  • 205,898
  • 23
  • 218
  • 273
-1

You're looking for a container_of macro. This is widely used in Linux kernel. Refer to Understanding container_of macro in the Linux kernel to learn how it works.

VIPPER
  • 326
  • 4
  • 24