Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Nermal

Moderator
Original poster
Staff member
Dec 7, 2002
21,194
4,855
New Zealand
Hi everyone,

I'm trying to learn plain old C; I'm reasonably proficient with C# but new to C. I'm trying to figure out whether there is a way to do a "calculated member" (for want of a better name) in a struct. For example, starting with the following:

Code:
typedef struct {
    int Width;
    int Height;
} Rectangle;

I'd like to be able to add some sort of "int Area = Width * Height;". It'll obviously be more complicated than that, but is this sort of thing possible in C? I've created a function called Rectangle_Area that takes a Rectangle and returns an int, but I'm not sure whether there's a way to "link" it into the main struct. I don't yet know all the terms that I should be searching for so can someone please help a newbie out? :)
 
Last edited:
Do you mean that you would like to add a function to the struct? You can do that with a function pointer, but it's a bit convoluted since you can not refer to the struct itself from within the struct. This is a benefit of OOP languages like C++ or Obj-C they both have a "this" pointer which does that. In the case of C, you'd need to add the struct itself as an argument to the function.

Edit: an example

Code:
#include <stdio.h>

typedef struct rectangle{
  int width;
  int height;
  int (*area)(struct rectangle *rect);
} rectangle;

int area(rectangle *rect) {
  return rect->width * rect->height;
}

int main(void)
{
  rectangle rect = {2, 3, area};

  printf("Area: %d\n", rect.area(&rect));

  return 0;
}

I need to type out the struct name in the struct declaration or use a void pointer or the area function declaration don't know what a rectangle is since that appear the row just below.
 
Last edited:
Aha! That does indeed work so thanks for that. I've also learned the magic words "function pointer" to put into Google :)
 
Aha! That does indeed work so thanks for that. I've also learned the magic words "function pointer" to put into Google :)

They can be quite useful if you are trying to make a generic function that need to work on many data types. An example can be found in the stdlib's qsort() function. Since this sorting function should be able to sort anything, from numbers, strings, to rectangles, you need to add a compare function that knows what it means to be less, greater or equal to something. From the function declaration in the man page:

Code:
qsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *));

It's the last parameter here, and it also takes two arguments, both void pointers since the function needs to be able to sort anything. Sometimes in libraries like CoreFoundation or CoreAudio for example, you'll see the arguments as a separate "context" parameter, which is even more generic, you are then able to add any amount of argument to your supplied function in the context as a struct.
 
With the code example from subsonix above you can also simplify the invocation by defining a macro:

Code:
/* Invoke method Y on struct X.*/
#define invoke(X, Y) X.Y(&X)

So the printf then can become:
Code:
printf("Area: %d\n", invoke(rect, area));

This is effectively the beginning of implementing object-oriented programming model. If this is your goal, it is worth looking at ooc and GObject as related efforts.
 
Using a #define looks like an interesting idea, but give me too many ideas and I'll end up using C# syntax in my C code :)
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.