On 11/12/19 14:32, Greg Kurz wrote: > QOM interfaces allow a limited form of multiple inheritance, at the > condition of being stateless. That is, they cannot be instantiated > and a pointer to an interface shouldn't be dereferenceable in any way. > This is achieved by making the QOM instance type an incomplete type, > which is, as mentioned by Markus Armbruster, the closest you can get > to abstract class in C. > > Incomplete types are widely used to hide implementation details, but > people usually expect to find at least one place where the type is > fully defined. The fact that it doesn't happen with QOM interfaces is > quite disturbing, especially since it isn't documented anywhere as > recently discussed in this thread: > > https://lists.gnu.org/archive/html/qemu-devel/2019-12/msg01579.html > > Amend the documentation in the object.h header file to provide more > details about why and how to implement QOM interfaces using incomplete > types. > > Signed-off-by: Greg Kurz <gr...@kaod.org> > --- > include/qom/object.h | 10 ++++++++-- > 1 file changed, 8 insertions(+), 2 deletions(-) > > diff --git a/include/qom/object.h b/include/qom/object.h > index 128d00c77fd6..5cf98d2c4350 100644 > --- a/include/qom/object.h > +++ b/include/qom/object.h > @@ -200,8 +200,14 @@ typedef struct InterfaceInfo InterfaceInfo; > * > * Interfaces allow a limited form of multiple inheritance. Instances are > * similar to normal types except for the fact that are only defined by > - * their classes and never carry any state. You can dynamically cast an > object > - * to one of its #Interface types and vice versa. > + * their classes and never carry any state. As a consequence, a pointer to > + * an interface instance should always be of incomplete type in order to be > + * sure it cannot be dereferenced. That is, you should define the > + * 'typedef struct SomethingIf SomethingIf' so that you can pass around > + * 'SomethingIf *si' arguments, but not define a 'struct SomethingIf { ... > }'. > + * The only things you can validly do with a 'SomethingIf *' are to pass it > as > + * an argument to a method on its corresponding SomethingIfClass, or to > + * dynamically cast it to an object that implements the interface. > * > * # Methods # > * >
Queued, thanks. Paolo