LWN.net Logo

Quotes of the week

OTOH I've been exposed to source code of some secret sauce drivers. That makes me believe that in a lot of cases the reason for not disclosing the driver code is that publishing might put the innocent and unprepared reader in danger of gastric ulcer and eyecancer.

So I commit this change for health protection reasons.

Thomas Gleixner

If you know physics, think of a release (and the tag is associated with it) as "collapsing the wave function". Before that, the outside world doesn't know the exact state of your tree (they may have good guesses based on the patches they've seen) - after that, it's "done". You cannot change it. And more importantly, other people can see the state, and measure it, and depend on it.
Linus Torvalds

Oh, but I have a sick and twisted mind. And I'm incredibly smart and photogenic too...

Ready? You *will* go blind - blinded by the pure beauty and intellect in this thing:

    #define IS_DEFINED(x) (__stringify(CONFIG_##x)[0]=='1')

That really is a piece of art. I'm expecting that the Guggenheim will contact me any moment now about it.

Linus Torvalds
(Log in to post comments)

Quotes of the week

Posted Apr 19, 2012 11:27 UTC (Thu) by iq-0 (subscriber, #36655) [Link]

Linus "crowdsourced" the quoted macro on google+

And later referred to that from the 3.4-rc3 announcement also on google+

Quotes of the week

Posted Apr 19, 2012 13:14 UTC (Thu) by nix (subscriber, #2304) [Link]

The crowdsourced hack is a sheer work of art. Unlike Linus's solution it's a kick-yourself-at-how-obvious-it-is-in-hindsight thing as well.

Quotes of the week

Posted Apr 19, 2012 17:08 UTC (Thu) by flewellyn (subscriber, #5047) [Link]

My CPP macro-fu is weak. How the hell does that monstrosity even WORK?

Quotes of the week

Posted Apr 19, 2012 17:44 UTC (Thu) by BenHutchings (subscriber, #37955) [Link]

Assuming FOO is defined and BAR is not, I believe the expansion goes like this:
   is_set(FOO)
=> is_set_(1)
=> is_set__(macrotest_1)
=> is_set___(, 1, 0)
=> 1

   is_set(BAR)
=> is_set_(BAR)
=> is_set__(macrotest_BAR)
=> is_set___(macrotest_BAR 1, 0)
=> 0

Quotes of the week

Posted Apr 19, 2012 17:56 UTC (Thu) by wahern (subscriber, #37304) [Link]

You can't index strings in the pre-processor, so it's not using just the pre-processor.

__stringify uses the CPP # operator to convert a token into a string. It's almost always a pair of macros, because you need the indirection to allow the parameter (which may be composed of a CPP expression using the ## token pasting operator) to be replaced by any macro before applying the # operator. (Otherwise you could just the # without a macro invocation.) For example, this is very common:

#define STRINGIFY_(arg) #arg
#define STRINGIFY(arg) STRINGIFY_(arg)

Now, if you #define CONFIG_FOO 1, then __stringify(CONFIG_FOO) yields a string, "1". "1"[0] yields '1'.

__stringify(CONFIG_BAR), where CONFIG_BAR isn't defined, yields a string, "CONFIG_BAR". That's because CONFIG_BAR isn't defined so remains as-is. "CONFIG_BAR"[0] then yields 'C'.

There're lots of cool things you can do with the C pre-processor, including multi-dispatch based on the number of arguments using C99 variable-argument list macros and some cool macro magic--legal magic, mind you. (This also works in Visual Studio MSC because, although not even remotely C99 compliant, it at least does support __VA_ARGS__.)

With C11 you can use the new _Generic keyword to also implement multi-dispatch based on argument type, so in C11 you can implement full-blown function overloading in ISO C.

Quotes of the week

Posted Apr 19, 2012 19:35 UTC (Thu) by jzbiciak (✭ supporter ✭, #5246) [Link]

I forget... do you need two levels of indirection for STRINGIFY to work (ie. one more than you show there)?

In any case, that trick is the cat's meow. Nice.

Quotes of the week

Posted Apr 19, 2012 20:33 UTC (Thu) by wahern (subscriber, #37304) [Link]

You don't need more than two for STRINGIFY to work reliably, but the # and ## operators only work in macro replacement lists. In this case, I guess IS_DEFINED provides that extra level of indirection to do the CONFIG_##x pasting.

<sys/param.h> on Linux and BSD provide PASTE and XPASTE (the latter being more commonly used to ensure parameters are evaluated properly) to do this pasting in an ad hoc manner.

Quotes of the week

Posted Apr 28, 2012 7:42 UTC (Sat) by mmaroti (guest, #84368) [Link]

Just for the record, I had this solution before :)

http://stackoverflow.com/questions/5464170/using-definedm...

Copyright © 2012, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds