widl: Do not generate empty Vtbl structure for empty interfaces.

Thomas Faber thfabba at gmx.de
Sun Jun 23 06:44:29 CDT 2013


This causes widl to generate a dummy member in the Vtbl structure of an
empty interface.
Empty structures are not allowed in C (and MSVC will refuse to compile
a header file containing one).

The only example I know of this is the nsCycleCollectionISupports
interface in mshtml's nsiface.idl.
The resulting structure will take this format in the header:

typedef struct nsCycleCollectionISupportsVtbl {
    BEGIN_INTERFACE

#ifndef __cplusplus
    char dummy;
#endif

    END_INTERFACE
} nsCycleCollectionISupportsVtbl;


I can remove the ifndef __cplusplus if desired; but empty structures are
syntactically valid in C++, and modern compilers should in fact generate
a one-byte structure anyway.

The added member is not a problem because ever accessing the vtable of an
empty interface would be wrong anyway, and vtables of child classes that
actually add methods will not contain it.

An alternative solution would be not to generate a vtable structure at all,
and instead add a dummy member to the class directly. That would be in line
with what the defined(__cplusplus) && !defined(CINTERFACE) case results in,
but require a slightly larger change to widl.
-------------- next part --------------
From 82b514c8974537bf5839774b7fbf06905a213786 Mon Sep 17 00:00:00 2001
From: Thomas Faber <thfabba at gmx.de>
Date: Sun, 23 Jun 2013 13:19:52 +0200
Subject: widl: Do not generate empty Vtbl structure for empty interfaces.

---
 tools/widl/header.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/tools/widl/header.c b/tools/widl/header.c
index 2f275c7..118e150 100644
--- a/tools/widl/header.c
+++ b/tools/widl/header.c
@@ -975,6 +975,15 @@ static void do_write_c_method_def(FILE *header, const type_t *iface, const char
 
   if (type_iface_get_inherit(iface))
     do_write_c_method_def(header, type_iface_get_inherit(iface), name);
+  else if (type_iface_get_stmts(iface) == NULL)
+  {
+    fprintf(header, "#ifndef __cplusplus\n");
+    indent(header, 0);
+    fprintf(header, "char dummy;\n");
+    fprintf(header, "#endif\n");
+    fprintf(header, "\n");
+    return;
+  }
 
   STATEMENTS_FOR_EACH_FUNC(stmt, type_iface_get_stmts(iface))
   {
-- 
1.8.1.5


More information about the wine-patches mailing list