[prev in list] [next in list] [prev in thread] [next in thread]
List: linux-sparse
Subject: Re: more sparse borkage.
From: Linus Torvalds <torvalds () osdl ! org>
Date: 2004-03-25 20:19:07
Message-ID: Pine.LNX.4.58.0403251157300.1106 () ppc970 ! osdl ! org
[Download RAW message or body]
Ok,
as I fixed a confusion I had about type-name visibility that Dave Jones
found, and that affected the hisax/st5481_usb ISDN driver, I realized just
how easy it is to support types as "real entities" in expressions, because
I needed to trigger a warning on such a condition anyway.
So instead of warning about it, I just implemented a limited form of
"types as first-class citizens".
What I wanted to do is to basically do the type equality testign that the
kernel "max()" macro does with that strange "(void) (&_x == &_y)"
comparison:
#define max(x,y) ({ \
typeof(x) _x = (x); \
typeof(y) _y = (y); \
(void) (&_x == &_y); \
_x > _y ? _x : _y; })
and make it a real type comparison that could be used to actually
parameterize a macro.
The strange comparison works fine for gettign the warning we want in
"max()", but it doesn't allow us to _behave_ differently depending on the
types. The kernel user access macros use "sizeof" to behave pseudo-
differently depending on types, but you can't do anything fancy with it.
In other words, I wanted to be able to do something like this
#define format(x) \
(typeof(x) == int ? "%d" : \
typeof(x) == long ? "%ld" : "%x")
#define print(x) printf(format(x),x)
and it should just work (and work even if "int" and "long" happen to be
the same size).
Now, the above doesn't actually work right now, for a silly reason: the
"(typeof(x)" thing is parsed as a cast, and then the code is unhappy about
not getting the ending ")". In other cases the "typeof" is expected to be
the start of a variable declaration, not an expression. But both those
cases can be worked around with a strange syntactic trick:
#define format(x) \
(0, typeof(x) == int ? "%d" : \
typeof(x) == long ? "%ld" : "%x")
#define print(x) printf(format(x),x)
and this does indeed work, and because all of it is obviously compile-time
constants, it even folds correctly.
You can try the above with the x86 toy backend in the current BK tree, and
you'll see how it all is done correctly.
I think the above is a cool feature. It's _especially_ cool if I ever
actually get around to implementing the untyped inline functions, ie what
I really want to work is something like
static inline max(a,b)
{
if (typeof(a) != typeof(b))
__compile_time_warning();
return a > b ? a : b;
}
where all argument types are inherited from the context of the calling
process (I may have problems with the return type, sadly).
Cool, or crazy.. You decide.
Linus
-
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic