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 664284 - Compiler errors for non-typedef'd delegates in existing C code
Compiler errors for non-typedef'd delegates in existing C code
Status: RESOLVED DUPLICATE of bug 794920
Product: vala
Classification: Core
Component: Delegates
unspecified
Other Linux
: Normal normal
: ---
Assigned To: Vala maintainers
Vala maintainers
Depends on:
Blocks:
 
 
Reported: 2011-11-17 16:35 UTC by Andre Masella
Modified: 2018-05-19 21:14 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
first attempt to force declaration of anonymous delegates from C code (2.15 KB, patch)
2011-11-17 16:36 UTC, Andre Masella
none Details | Review
Create anonymous delegates for C function pointers which are not typedef'd (17.20 KB, patch)
2011-11-19 15:29 UTC, Andre Masella
none Details | Review
sample code to generate various delegates (687 bytes, text/x-vala)
2011-11-19 15:30 UTC, Andre Masella
  Details

Description Andre Masella 2011-11-17 16:35:55 UTC
When working on #663633, I noticed a problem that has cropped up in other VAPIs. The following code will fail to compile:

void main() {
Posix.GlobErrorFunction f;
}

GlobErrorFunction is the delegate of errfunc from glob:

int glob(const char *pattern, int flags,
                int (*errfunc) (const char *epath, int eerrno),
                glob_t *pglob);

The problem is that it was never typedef'd. As I see it, there are four options:

Option 1) Modify the existing C code. -- This is not always possible.
Option 2) Include a supplemental header file with the missing definitions. This can be done, but there isn't a good infrastructure for dealing with this (do they go in the vapidir? should the vapidir be given as an include dir to the compiler?) and it means duplicating the definitions.
Option 3) Change the ccode gen to emit code like:
int(*f)(char*,int);
in the above example. This would have to be the case for parameters and variable declarations.
Option 4) Emit the typedef for external delegates in the generated code just like the compiler does for internal delegates.

I have written a patch that does Option 4...I'm not sure it does it well though.  It adds a CCode always_declare which overrides the externality check during code generation and causes the typedef to be emitted. I am not sure, but I suspect it would be possibly to multiply emit that typedef once header files or not emit it in the right places.

Is there a better way to do this?
Comment 1 Andre Masella 2011-11-17 16:36:46 UTC
Created attachment 201598 [details] [review]
first attempt to force declaration of anonymous delegates from C code
Comment 2 Andre Masella 2011-11-18 11:13:18 UTC
Also for note, I've been working on libgit2 binding and tried option 1: https://github.com/libgit2/libgit2/pull/483
They would prefer options 3 or 4.
Comment 3 Luca Bruno 2011-11-18 18:39:22 UTC
It's better option 3 by fixing the bug in producing the code for the anonymous function pointer. In particular see bug 621220. The patch there still needs some improvement.
Comment 4 Andre Masella 2011-11-19 15:28:57 UTC
Okay. I don't understand how bug 621220 is relevant. Here's a version that creates ret(*name)()-style function parameters, global declarations, local variables, temporary variables and fields.

I've chosen to to make the argument list empty because there doesn't seem to be an easy way to use existing code to generate the parameter list as a string and it is still valid C without the parameter list. Should this get an arglist? If so, how to generate it? The other problem with generating is the following valid code would recurse infinitely:
[CCode(anonymous_delegate = true)]
public delegate int Foo(Foo f);

There are situations where accessing the CCode attributes is done different. I'm not sure if there is a preference, but I've tried to follow local convention. Please advise.

I've also attached some sample code that generates various anonymous delegates using the Posix.GlobErrorFunction.
Comment 5 Andre Masella 2011-11-19 15:29:44 UTC
Created attachment 201705 [details] [review]
Create anonymous delegates for C function pointers which are not typedef'd
Comment 6 Andre Masella 2011-11-19 15:30:35 UTC
Created attachment 201706 [details]
sample code to generate various delegates

Must be compiled with --pkg posix
Comment 7 Luca Bruno 2011-11-19 15:49:53 UTC
Simply cname="(*...the signature)". And it depends on that bug.
Comment 8 Andre Masella 2011-11-19 16:26:43 UTC
After discussion on IRC:

Luca suggested something like:
[CCode(cname = "int(*)()")]
delegate int GlobErrorFunc(string s, int i);
GlobErrorFunc foo;

The problem is that it generates the incorrect C code:
int(*)() foo;

Because of that awful declaration-reflects-use thing, it has to be defined as:
int(*foo)();

Furthermore, the last patch I submitted is buggy when it comes to high-order types. For instance:
GlobErrorFunc[] myfuncs;

should be:
int(*myfuncs[])();

but my code will generate:
GlobErrorFunc* myfuncs;

The same is true for pointers. Obviously, I can combine these things into nice monsters.

Making Option 4 work properly would require changing the idea that every declaration is an independent type and name that are, more or less, declared by "${type} ${name};".
Comment 9 Rico Tzschichholz 2018-05-19 21:14:09 UTC

*** This bug has been marked as a duplicate of bug 794920 ***