qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] object: Improve documentation of interfaces
@ 2019-12-11 13:32 Greg Kurz
  2019-12-11 13:35 ` Marc-André Lureau
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Greg Kurz @ 2019-12-11 13:32 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Peter Maydell, Daniel P. Berrange, Markus Armbruster, qemu-devel,
	Marc-André Lureau, Philippe Mathieu-Daudé,
	David Gibson

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 <groug@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 #
  *



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] object: Improve documentation of interfaces
  2019-12-11 13:32 [PATCH] object: Improve documentation of interfaces Greg Kurz
@ 2019-12-11 13:35 ` Marc-André Lureau
  2019-12-11 17:01 ` Markus Armbruster
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Marc-André Lureau @ 2019-12-11 13:35 UTC (permalink / raw)
  To: Greg Kurz
  Cc: Peter Maydell, Daniel P. Berrange, QEMU, Markus Armbruster,
	Paolo Bonzini, Philippe Mathieu-Daudé,
	David Gibson

On Wed, Dec 11, 2019 at 5:33 PM Greg Kurz <groug@kaod.org> 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 <groug@kaod.org>

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>

> ---
>  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 #
>   *
>
>


-- 
Marc-André Lureau


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] object: Improve documentation of interfaces
  2019-12-11 13:32 [PATCH] object: Improve documentation of interfaces Greg Kurz
  2019-12-11 13:35 ` Marc-André Lureau
@ 2019-12-11 17:01 ` Markus Armbruster
  2019-12-12  0:37 ` David Gibson
  2019-12-12  8:12 ` Paolo Bonzini
  3 siblings, 0 replies; 5+ messages in thread
From: Markus Armbruster @ 2019-12-11 17:01 UTC (permalink / raw)
  To: Greg Kurz
  Cc: Peter Maydell, Daniel P. Berrange, qemu-devel, Markus Armbruster,
	Marc-André Lureau, Paolo Bonzini,
	Philippe Mathieu-Daudé,
	David Gibson

Greg Kurz <groug@kaod.org> writes:

> 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 <groug@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 #
>   *

Reviewed-by: Markus Armbruster <armbru@redhat.com>



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] object: Improve documentation of interfaces
  2019-12-11 13:32 [PATCH] object: Improve documentation of interfaces Greg Kurz
  2019-12-11 13:35 ` Marc-André Lureau
  2019-12-11 17:01 ` Markus Armbruster
@ 2019-12-12  0:37 ` David Gibson
  2019-12-12  8:12 ` Paolo Bonzini
  3 siblings, 0 replies; 5+ messages in thread
From: David Gibson @ 2019-12-12  0:37 UTC (permalink / raw)
  To: Greg Kurz
  Cc: Peter Maydell, Daniel P. Berrange, Markus Armbruster, qemu-devel,
	Marc-André Lureau, Paolo Bonzini,
	Philippe Mathieu-Daudé

[-- Attachment #1: Type: text/plain, Size: 2607 bytes --]

On Wed, Dec 11, 2019 at 02:32:41PM +0100, 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 <groug@kaod.org>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

> ---
>  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 #
>   *
> 

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] object: Improve documentation of interfaces
  2019-12-11 13:32 [PATCH] object: Improve documentation of interfaces Greg Kurz
                   ` (2 preceding siblings ...)
  2019-12-12  0:37 ` David Gibson
@ 2019-12-12  8:12 ` Paolo Bonzini
  3 siblings, 0 replies; 5+ messages in thread
From: Paolo Bonzini @ 2019-12-12  8:12 UTC (permalink / raw)
  To: Greg Kurz
  Cc: Peter Maydell, Daniel P. Berrange, Markus Armbruster, qemu-devel,
	Marc-André Lureau, Philippe Mathieu-Daudé,
	David Gibson

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 <groug@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



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2019-12-12  8:13 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-11 13:32 [PATCH] object: Improve documentation of interfaces Greg Kurz
2019-12-11 13:35 ` Marc-André Lureau
2019-12-11 17:01 ` Markus Armbruster
2019-12-12  0:37 ` David Gibson
2019-12-12  8:12 ` Paolo Bonzini

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).