After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 785554 - glib-genmarshal: wrap prototypes in G_{BEGIN,END}_DECLS.
glib-genmarshal: wrap prototypes in G_{BEGIN,END}_DECLS.
Status: RESOLVED FIXED
Product: glib
Classification: Platform
Component: gobject
unspecified
Other All
: Normal normal
: ---
Assigned To: gtkdev
gtkdev
Depends on:
Blocks:
 
 
Reported: 2017-07-29 07:11 UTC by Mihai Moldovan
Modified: 2017-08-07 16:07 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Wrap prototypes correctly. (1.47 KB, patch)
2017-07-29 07:12 UTC, Mihai Moldovan
committed Details | Review
genmarshal: Generate C++ guards in compatibility mode (2.54 KB, patch)
2017-08-01 10:38 UTC, Emmanuele Bassi (:ebassi)
rejected Details | Review

Description Mihai Moldovan 2017-07-29 07:11:17 UTC
Since --header --body has been deprecated and replaced with --body --prototypes, the generated body is not wrapped with G_{BEGIN,END}_DECLS any longer.

Projects using C++ break due to that.

Automatically wrap prototypes individually in G_{BEGIN,END}_DECLS instead.
Comment 1 Mihai Moldovan 2017-07-29 07:12:37 UTC
Created attachment 356538 [details] [review]
Wrap prototypes correctly.
Comment 2 Emmanuele Bassi (:ebassi) 2017-08-01 10:29:01 UTC
Review of attachment 356538 [details] [review]:

::: gobject/glib-genmarshal.in
@@ +557,3 @@
     '''Generate a marshaller declaration with the given @visibility. If @va_marshal
     is True, the marshaller will use variadic arguments in place of a GValue array.'''
+    signature = ['G_BEGIN_DECLS']

I'm not really a fan of doing this unconditionally… Not everyone is using a C++ compiler, and I don't know how much of an impact this has.
Comment 3 Emmanuele Bassi (:ebassi) 2017-08-01 10:30:57 UTC
Personally, I'd rather you changed the project to use two separate invocations - one for the header and one for the body; that would be backwards compatible, and would not require hacks.

I also understand keeping backward compatibility, but I honestly think we should nudge people in doing the right thing, now that we have a chance.
Comment 4 Emmanuele Bassi (:ebassi) 2017-08-01 10:32:04 UTC
Maybe we should call `G_BEGIN_DECLS` and `G_END_DECLS` in the whole body, when in compatibility mode.
Comment 5 Mihai Moldovan 2017-08-01 10:33:28 UTC
That's fine. If using a C compiler, G_{BEGIN,END}_DECLS will be defined to an empty string.
Comment 6 Emmanuele Bassi (:ebassi) 2017-08-01 10:38:58 UTC
Created attachment 356710 [details] [review]
genmarshal: Generate C++ guards in compatibility mode

When using `--header --body`, we should generate the C++ guards, as we
generate the prototypes for the marshallers.
Comment 7 Mihai Moldovan 2017-08-01 10:40:46 UTC
The project I hit this bug on is actually using two invocations to create a header and implementation file. They probably should not be using --header or --prototypes with --body at all - but by default, the body does not include any prototypes header file because it can't know if people will actually be generating a header file and if they do how it will be called.

They probably should be using only --body, yes. Although that means that they also need to specify the generated header file (reasoning above.)

Wrapping everything in C_{BEGIN,END}_DECLS is pretty much the old behavior (stemming from --header), yeah.

I think we can do this more fine-grained though, by only wrapping the prototypes. That should also hold for the implementations.
Comment 8 Emmanuele Bassi (:ebassi) 2017-08-01 10:46:11 UTC
(In reply to Mihai Moldovan from comment #7)
> The project I hit this bug on is actually using two invocations to create a
> header and implementation file. They probably should not be using --header
> or --prototypes with --body at all - but by default, the body does not
> include any prototypes header file because it can't know if people will
> actually be generating a header file and if they do how it will be called.

That's usually solved, compatibly, by using a compound call, e.g.:

  ( echo '#include "foo-marshal.h"' &&
    glib-genmarshal --body foo-marshal.list ) > foo-marshal.c

> I think we can do this more fine-grained though, by only wrapping the
> prototypes. That should also hold for the implementations.

Personally, I'm much more confident in using a global C++ guard; glib-genmarshal only guarantees you it's generating C code, not C++. Even if valid C code is somewhat valid C++ code *today*, I cannot make you any guarantee about whatever we generate in the future.
Comment 9 Mihai Moldovan 2017-08-01 11:00:25 UTC
(In reply to Emmanuele Bassi (:ebassi) from comment #8)
> That's usually solved, compatibly, by using a compound call, e.g.:
> 
>   ( echo '#include "foo-marshal.h"' &&
>     glib-genmarshal --body foo-marshal.list ) > foo-marshal.c

The better way to handle this would probably be passing --include-header foo-marshal.h. That is what I was referencing. The project I hit that on (vte) doesn't do any of that, though, which is probably a(/their) bug.


> Personally, I'm much more confident in using a global C++ guard;
> glib-genmarshal only guarantees you it's generating C code, not C++. Even if
> valid C code is somewhat valid C++ code *today*, I cannot make you any
> guarantee about whatever we generate in the future.

That won't help anyone. 'extern "C"' only changes linkage, nothing else. It's a good idea and I agree in theory, but practically that's sadly not what 'extern "C"' provides.
Comment 10 Emmanuele Bassi (:ebassi) 2017-08-07 16:02:30 UTC
Review of attachment 356538 [details] [review]:

Okay, let's go with this one.
Comment 11 Emmanuele Bassi (:ebassi) 2017-08-07 16:03:13 UTC
Review of attachment 356710 [details] [review]:

We're going to use unconditional guards around prototypes, in case we end up compiling the marshallers with a C++ compiler.