dstep icon indicating copy to clipboard operation
dstep copied to clipboard

typedef function prototypes don't retain arguments

Open jblachly opened this issue 3 years ago • 5 comments

typedef char *kgets_func(char *, int, void *);

int f(char *s, kgets_func *fgets, void *fp);

int g(char *s, char* (*fun)(char *, int, void *), void *fp);

Results in:

extern (C):

alias kgets_func = char* function (char*, int, void*);

int f (char* s, char* function () fgets, void* fp);

int g (char* s, char* function (char*, int, void*) fun, void* fp);

Note f was not translated correctly; its second parameter takes type char* function() but should take char* function(char* int, void *) or more simply kgets_func via the alias.

jblachly avatar Nov 24 '20 03:11 jblachly

Actually, thinking more carefully about the title, I haven't proved that the typedef does not retain the function arguments, but I THINK that is the case given that g translates correctly

jblachly avatar Nov 24 '20 03:11 jblachly

The AST looks different for f and g. I guess that's why it fails to do a proper translation. Are you trying to create bindings for an existing library? Or is there a reason to declare f like that?

Based on the title of this issue, I think you're misunderstanding the code. kgets_func is not a function pointer, it's a function prototype. Then it becomes a function pointer when you declare parameter fgets. You might be looking for this code:

typedef char *(*kgets_func)(char *, int, void *);
int f(char *s, kgets_func fgets, void *fp);

Which is properly translated to:

extern (C):

alias kgets_func = char* function (char*, int, void*);
int f (char* s, kgets_func fgets, void* fp);

jacob-carlborg avatar Nov 24 '20 08:11 jacob-carlborg

The example you have provided is still a bug. But it might not be the code you want to write.

jacob-carlborg avatar Nov 24 '20 08:11 jacob-carlborg

f comes directly from a library to which I maintain bindings:

    typedef char *kgets_func(char *, int, void *);
    
    int kgetline(kstring_t *s, kgets_func *fgets_fn, void *fp);

https://github.com/samtools/htslib/blob/51275bcbda6d1e0849d0e50d0edd13814d38ebd1/htslib/kstring.h#L116-L118

jblachly avatar Nov 24 '20 14:11 jblachly

I see now it is a function prototype. C programmer habit of attaching pointer operator to the RHS drives me crazy.

typedef char* kgets_func(char *, int, void*) is more clear

Either way, appreciate insight into the bug as it requires manual intervention after dstep

jblachly avatar Nov 24 '20 15:11 jblachly