Nat! bio photo

Nat!

Senior Mull

Twitter Github Twitch

C Inheritance continued, putting functions into a struct

Continued from Inheritance in C would need a simple compiler hack. It has been updated

Member functions in C, could look like this:

struct x
{
   char   *name;

   static inline char   *get_name( struct x *p)
   {
      return( p->name);
   }
};
  1. You can have only static inline function definitions inside a struct. It follows the usual behaviour of static inline functions.
  2. It would be an error to define a function, that has the same name as an instance variable.
  3. The parameters of the inline function are completely free, so the struct pointer or variable is not an implicit parameter (like this in C++).
  4. Each struct is its own namespace, a member function is not globally declared.

The syntax would be similiar to C++ to access these shortened functions:

   struct x   a;
   struct x   *b;
   ...
   printf( "a=%s\n", a.get_name( &a));
   printf( "b=%s\n", b->get_name( b));

Inheritance

Combined with the inheritance scheme detailed in Inheritance in C would need a simple compiler hack, this allows a simple form of function inheritance.

If a struct has another struct as it’s first member, it inherits all the first member structs functions into its namespace.

e.g. y inherits from x:

struct x
{
   char   *name;

   static inline char   *get_name( struct x *p)
   {
      return( p->name);
   }
};

struct y
{
   struct x  base;
};

...
	struct  y  c;
...
	printf( "%s\n", c.get_name( &c));

Because of the type relaxation detailed in the first post, this would not make the compiler complain about using struct y * types as struct x * arguments.

Gah, my function is too big for inlining ?

It would IMO be too obscure, to allow extern declarations in the struct. Then the API programmer would either have to know a name shortening scheme, so that he could give the proper function name to the extern function

// do not want this
char   *_foo_get_name( struct _foo *p)
{
	...
   return( a);
}

or one would have to write the complete logic into the header file, which is un-C like.

The solution for non-inlineable or hidden functions is to write it like this:

static inline char   *get_name( struct x *p)
{
   extern int   __foo_get_name( struct x *p);

   return( __foo_get_name( p));
}

Advantages

  • Autocompletion possible based on the variable (pretty huge)
  • Inheritance of functions across types
  • Simple to implement, shouldn’t break anything
  • Less typework for the API user as inherited functions don’t come with the baggage of inherited struct prefixes (like x_get_name in the example from Inheritance in C would need a simple compiler hack)

Disadvantages

  • C becomes more complex
  • Writing larger or non-opensource functions for data structures need a wrapping inline declaration

Post a comment

All comments are held for moderation; basic HTML formatting accepted.

Name:
E-mail: (not published)
Website: