Hacker News new | past | comments | ask | show | jobs | submit login
Self-inlining anonymous functions in C++ (might.net)
48 points by adg001 on April 27, 2010 | hide | past | favorite | 11 comments



This is truly revolting, offensive code. Unless you like C++ template metaprogramming, I recommend you don't look.

:)


(Edit: fixed formatting) Revolting? I think that's a pretty good, if complex, example of "pushing the limits". IMHO, the label "revolting" is reserved for code like this:

  Derived() : Base() {
    THISCALL(0x535AA0);
    *(DWORD*)this = 0x7E1AF4;
  }
That's the kind of code I get to write in my hobby project.


It's using the type system to encode an arithmetic expression, with unique types for every distinct subtree; and then using statically-dispatched calls to inlined methods to get the compiler to embed the tree in-place, so that the optimizer's constant folding can evaluate the tree. The amount of code and data that's being shifted around and manipulated inside the compiler to generate a rather trivial end effect is what's offensive to me. If C++ were slightly more expressive, the technique would be unnecessary; but some C++ acolytes actually extol these kinds of techniques as a feature!


The technique is unnecessary, regardless as to C++ - its just a different way to write code.


This is pretty cool - the final compiled code looks pretty tidy considering the hoops being jumped through. :)


If you are interested in this subject, you might find the following pertinent:

http://www.boost.org/doc/libs/1_42_0/doc/html/lambda.html

and as someone posted here before:

http://gcc.gnu.org/projects/cxx0x.html

There's also an interview with a "brief" summary from Scott Meyers at http://www.se-radio.net/podcast/2010-04/episode-159-c0x-scot... that mentions lambda functions.


Wow. Things that look like expressions, but are most definitely not, through the magic of operator overloading. So you can translate some expressions straightforwardly, but other expressions not, with the cases for what works and doesn't requiring careful thought.

So this works:

    for_each(vp.begin(), vp.end(), cout << *_1 << '\n');
This doesn't:

    for_each(vp.begin(), vp.end(), cout << '\n' << *_1);
But this does:

    for_each(vp.begin(), vp.end(), cout << constant('\n') << *_1);
Considering how complex it is to figure out what works and what doesn't in that lambda slot, I'm not sure it's worth the effort. Of course I'm not a C++ programmer, and this is yet another reason why that might not be such a bad thing.

(Note: this is regarding Boost lambda, if that wasn't clear.)


Considering how complex it is to figure out what works and what doesn't in that lambda slot, I'm not sure it's worth the effort.

I am a C++ programmer, and that's exactly the conclusion I came to regarding Boost's lambda. I use Boost's bind library all the time, though.

But! C++0x has real lambdas, so we won't have to resort to this trickery much longer.


Another good intro to lambdas and more: http://blogs.msdn.com/vcblog/archive/2008/10/28/lambdas-auto... . It's for Microsoft's VC++ (including the free Express edition I'm using right now), not GCC, but the syntax is obviously the same in both cases.


Feels like somebody doesn't trust #define's for their C++ code. While you don't get the type "safety" you get something thats a bit more natural.


You can't do this with #define alone. You can pass these "functions" around arbitrarily, and it still works.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: