Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't pass type as named macro parameter #157

Open
a-p-jo opened this issue Nov 16, 2021 · 3 comments
Open

Don't pass type as named macro parameter #157

a-p-jo opened this issue Nov 16, 2021 · 3 comments

Comments

@a-p-jo
Copy link

a-p-jo commented Nov 16, 2021

Instead of :

#define kvec_t(type) struct { size_t n, m; type *a; }

do :

#define kvec_t(...) struct { size_t n, m; __VA_ARGS__ *a; }

C macros are parsed in a very literal way, with no contextual awareness of {}, etc. So while struct { int x, y; } is a valid type, kvec_t(type) will split it into two arguments at the first , and then complain about too many parameters, while kvec_t(...) will paste the entire thing in place of __VA_ARGS__.

@jmarshall
Copy link
Contributor

The body of the #define constructs a new type from the argument by sticking a * on the end. This is sufficient to construct a pointer type pointing to the original type in lots of cases, but not for all C types. So in general there is no hope and you need to typedef a name for your type. So you might as well make a typedef (or even just add a struct tag) for your anonymous struct and pass that to kvec_t, in which case the existing definition of the macro is fine.

@a-p-jo
Copy link
Author

a-p-jo commented Nov 16, 2021

@jmarshall Indeed, it is not so common to write anonymous structs by hand again and again, and even a macro expanding to it would evade this. However, as it stands, T is not capable of reliably being every legal type. The purpose of this issue is to bring this to notice in case it was not known. I understand that it is challenging to write variadic macros like this, I myself encountered this issue when implementing a macro library and looking at kvec for ideas.

@a-p-jo
Copy link
Author

a-p-jo commented Nov 17, 2021

There's a further issue. ... cannot be a function pointer, or array pointer and so on and so forth. A serious solution would require typeof(__VA_ARGS__) *, which might even be standardised in C23, although as yet it is a GNUC extension with similarly named counterparts in nearly all compilers but varies in behaviour of discarding or preserving qualifiers.

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

No branches or pull requests

2 participants