Skip to content

structures forward declarations rework#23

Draft
mxyns wants to merge 1 commit into
msune:masterfrom
mxyns:forward_decls
Draft

structures forward declarations rework#23
mxyns wants to merge 1 commit into
msune:masterfrom
mxyns:forward_decls

Conversation

@mxyns
Copy link
Copy Markdown

@mxyns mxyns commented May 5, 2026

Hello msune,

A while back we tried to generate bindings for pmacct. Since some types of pmacct expose libcdada types, those types were also part of the generated bindings so we can create pmacct structures from other languages. Unfortunately, the way libcdada does forward declarations for its types causes issues with bindings generators.

Atm, from what I understand, libcdada does forward declarations (FD) as follows:

typedef void cdada_list_t;  

Then, the public API exposes cdada_list_t * which is just a sugared void *. I am unaware of the reasons the FDs were done like this. If there aren't any specific considerations, I believe it could be rewritten as:

typedef struct cdada_list_t cdada_list_t;

That would be, to my knowledge, a more standard way of doing FDs. As an added bonus, this gives stronger type-safety and type checks by forcing the developer to convert pointers explicitly.

I made this draft PR with a POC showing what such changes could look like, applied to lists. It is still rather crude but it compiles and passes the tests ran with make check. If you are interested in these changes, I could put in a bit of time to do the migration for your other data structures, when possible (I did not look at maps and such yet and don't know the feasability).

I know this is quite niche, and the original issue might partly be caused by the way binding generators are implemented. So I would totally understand if you didn't feel the need to address this now or ever.

@msune
Copy link
Copy Markdown
Owner

msune commented May 18, 2026

@mxyns,

Sorry for for the late reply!

Unfortunately, the way libcdada does forward declarations for its types causes issues with bindings generators.

Curious to know more. Do you have a branch where you are doing this work?

I am unaware of the reasons the FDs were done like this. If there aren't any specific considerations, I believe it could be rewritten as:

typedef struct cdada_list_t cdada_list_t;

I am,not sure why I used void (long time ago):

cdada_list_t *my_list;

In the approach you propose, the type is incomplete, as the actual definition of cdada_list_t will not (never) be known by the compiler. This is not a problem because you only work with pointers on the public API, and in the backend everything is typecasted. At the time I might just overlooked, and defined it as void to avoid any problem, without much thought.

Side note: I had experimented in the past with ETL in this branch to allow (optionally) to use ETL as a backend for the C++ standard library to reduce / eliminate entirely dynamic memory allocation (using stack), so that would change things quite a bit.

Let's ignore this for this discussion

Coming back to the proposal, I don't have an objection provided that this change is done across the codebase and doesn't modify the public API (which it doesn't) and compiles on all platforms and langs (which it will).

One thing I would really want though, is to separate typedef from fwd declaration, so that you can use struct cdada_list or cdada_list_t indistinctly, and it's clear what's a typedef and what it isn't:

struct cdada_list;  //fwd decl struct
typedef struct cdada_list cdada_list_t;

Thx!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants