-
Notifications
You must be signed in to change notification settings - Fork 254
Add typeas() and use it #1395
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
Add typeas() and use it #1395
Conversation
8e34501 to
d52ae9d
Compare
I just did a 'make dist', then committed the updates to the po and shadow.pot files. Closes shadow-maint#1395 Signed-off-by: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
This simplifies the implementation, allowing us to use _Generic(3) to replace _Static_assert(3), is_same_type(), and local variables. Local variables in macros can cause issues when nesting such macros. This also makes the code more readable, by having the type explicitly stated at call site. Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Have xxx_T() macros that only add type safety to the function they wrap. Have XXX() macros that do more magic; in this case, they deduce the comparison function that is appropriate for the type. This will allow using the xxx_T() macros in more complex cases, where the function can't be deduced just from the type. Signed-off-by: Alejandro Colomar <alx@kernel.org>
This macro is like typeof(), but requires that the input is a type name.
This macro is useful because it parenthesizes the type name, which
allows one to create pointers to arbitrary types. The following code
works for simple types:
T x;
T *p;
For example, that would work fine for 'int':
int x;
int *p;
However, that wouldn't work for types such as 'int[3]':
int[3] x;
int[3] *p;
But if we do instead
typeas(T) x;
typeas(T) *p;
now we can use 'int[3]' just fine:
typeof((int[3]){}) x;
typeof((int[3]){}) *p;
To understand this, we create a compound literal of type int[3], with
default values (zero, zero, zero), then get it's type, which is
obviously int[3]. And then we use that to declare a variable x of that
type, and a pointer p, which has type 'int(*)[3]'.
This would also work with something simpler. One could use typeof(T)
directly:
typeof(T) x;
typeof(T) *p;
However, typeof() doesn't require that the input is a type; it accepts
arbitrary input. The following is valid C:
typeof(42) x;
For our macro MALLOC(), where we want the second argument to be a type
name, we want to require that the argument is a type name. For that, we
need to use typeas().
Reported-by: Alejandro Colomar <alx@kernel.org>
Suggested-by: Thiago Adams <thiago.adams@gmail.com>
Suggested-by: Martin Uecker <uecker@tugraz.at>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
d52ae9d to
9dd442b
Compare
|
Reopening since this was incorrectly closed |
|
Holy cow. Github closed the issue that was in the Description? I didn't even |
It's even more funny. I've heard people had closed other projects' issues by having a Closes tag that linked to another repo. Github is quite funny. |
|
On Fri, Dec 05, 2025 at 06:29:17AM -0800, Alejandro Colomar wrote:
What we do is change the selector of _Generic(3). However, it's used as a callback in the same function (think of a macro that expands to just `cmp_int` within the lfind_() call). There, nothing changed.
oh, I see - it's a step more abstract than the way I was
processing it. Thank you.
|
typeas() is safer than typeof() in that it requires that the input is a type name.
And it is more generally useful than
(T *){}in that it accepts any type; T* doesn't work with array types nor function types.(This PR also does a few other changes that are needed before we can use typeas(), and which also make these APIs more readable, safer, and more useful.)
Revisions:
v1b
v1c