0

I have the to GLib classes Foo and DerivedFoo.

The Foo class has a bar () method:

typedef struct _FooClass
{
  GObjectClass parent_class;

  void (*bar) (Foo *self);
} FooClass;

The DerivedFoo class derives from Foo and implements the bar () method:

void derived_foo_bar (DerivedFoo *self);

static void
derived_foo_class_init (DerivedFooClass *klass)
{
  FooClass *foo_class = FOO_CLASS (klass);
  // Compiler warning appears here
  foo_class->bar = derived_foo_bar;
}

The warning message is:

warning: assignment from incompatible pointer type

The pointers are not compatible, because the type of the self parameter is different (Foo * vs. DerivedFoo *).

Is this the right way to implement virtual methods in GObject?

If so, can/should I do something about the compiler warning?

Jens Mühlenhoff
  • 14,565
  • 6
  • 56
  • 113
  • 1
    How does `DerivedFoo` derive from `Foo`? There is no inheritance in C. – atturri Apr 22 '16 at 20:09
  • This question is a good way to start an argument about the [strict aliasing rule](https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule). – user3386109 Apr 22 '16 at 20:27
  • You could cast it as `foo_class->bar = (void (*)(Foo *))derived_foo_bar;`. I guess judicious use of `typedef` and/or macros would make it look less ugly! – Ian Abbott Apr 22 '16 at 20:29
  • @atturi There is [inheritance in GObject](https://developer.gnome.org/gobject/stable/gobject-Type-Information.html#G-DECLARE-DERIVABLE-TYPE:CAPS). – Jens Mühlenhoff Apr 23 '16 at 11:00

1 Answers1

3

You leave the function prototype to respect the virtual base class, and typecast it in your function using glib macros/functions.

void derived_foo_bar (Foo *self);

static void
derived_foo_class_init (DerivedFooClass *klass)
{
  FooClass *foo_class = FOO_CLASS (klass);
  // Compiler warning appears here
  foo_class->bar = derived_foo_bar;
}

void derived_foo_bar (Foo *_self)
{
  DerivedFoo *self = DERIVED_FOO (self); /* or whatever you have named this macro, using the standard GLIB semantics */
 /* If self is not compatible with DerivedFoo, a warning will be issued from glib typecasting logic */
}
Stian Skjelstad
  • 2,277
  • 1
  • 9
  • 19