TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Lambdas for C – sort of

78 pointsby fogusover 5 years ago

7 comments

dragontamerover 5 years ago
The &quot;hackaday&quot; blog focuses on cool things that are typically (but not necessarily) impractical. He isn&#x27;t suggesting that this &quot;lambda&quot; be used. Instead, this is a stealth blog-post about &quot;__anon&quot;, as far as I can tell.<p>Which is really what hackaday is about: finding weird features in hardware&#x2F;compilers&#x2F;etc. etc. and using them in some manner. There&#x27;s a whole lot of obscure features of GCC that are being touched upon in this blogpost (nested functions, whatever is going on with $__anon$, etc. etc.). I can&#x27;t say that I can figure out exactly what is going on yet, but its kind of exciting to see all of these features get used at once.<p><a href="https:&#x2F;&#x2F;github.com&#x2F;wd5gnr&#x2F;clambda&#x2F;blob&#x2F;master&#x2F;clambda2.c" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;wd5gnr&#x2F;clambda&#x2F;blob&#x2F;master&#x2F;clambda2.c</a><p>EDIT: Unfortunately, it just segfaults for me at the moment.<p><pre><code> $ gcc --std=gnu99 clambda2.c $ .&#x2F;a.out Segmentation fault (core dumped) $ gcc --version gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0 </code></pre> This is Ubuntu on Windows, but I doubt that would make a difference.
评论 #20945012 未加载
评论 #20944146 未加载
评论 #20943812 未加载
评论 #20943709 未加载
评论 #20947139 未加载
kazinatorover 5 years ago
I&#x27;m not conviced that GCC defines the behavior of this, because the trick relies on defining a local function in a block scope, and then allowing it to escape from that block scope:<p><pre><code> { rettype foo(args ...) { ... } foo; } </code></pre> GCC local functions are &quot;downward funarg only&quot;, as far as I know. This would definitely be wrong:<p><pre><code> { int local = 42; rettype foo(args ...) { ... reference local ... } foo; } </code></pre> then, when <i>foo</i> is called, <i>local</i> no longer exists, which is bad news. The lambda macro doesn&#x27;t do this (the block doesn&#x27;t extend the enviornment; nothing is captured from there), and so maybe works by fluke.<p>Another thing to is that pointers to GCC local functions work via trampolines: pieces of executable machine code installed into the stack. When you use GCC functions, the linker has to mark the executable with a bit which says &quot;allow stacks to be executable&quot;. The default in most distros is non-executable stacks, which guards against stack overflow exploits.<p>(Speaking of trampolines, I&#x27;m not sure about the effective scope of those. If we lift a pointer to a local function inside a block, requiring a trampoline, and then that block terminates, is that trampoline scoped to the block or the function? If it&#x27;s scoped to the function, won&#x27;t it be overwritten if we execute that logic multiple times? If the trampoline is scoped to the block, then the invocation of foo is using an out-of-scope trampoline.
评论 #20944006 未加载
评论 #20944081 未加载
cryptonectorover 5 years ago
So, this doesn&#x27;t work because the scope of the statement-expression <i>is</i> the scope of the local function, so to use the function outside that scope (as TFA shows) is UB.<p>C w&#x2F; GCC&#x27;s local functions extensions is just not enough for lambda expressions. You have to declare the local function earlier than (and in scope of) the use site.<p>For example, an expression like this:<p><pre><code> float x = add_fns(1, lambda(float,(float x),{ return 2*x; }), lambda(float,(float x),{ return 3*x; })); </code></pre> may well assign 6.0 to x rather than 5.0 because the first lambda gets overwritten on the stack with the second. That&#x27;s if it works at all -- after all, we have UB here, and this could just summon cthulhu or anything else.
评论 #20943871 未加载
pjmlpover 5 years ago
Apparently the author forgot to look into clang blocks language extension.<p><a href="https:&#x2F;&#x2F;clang.llvm.org&#x2F;docs&#x2F;BlockLanguageSpec.html" rel="nofollow">https:&#x2F;&#x2F;clang.llvm.org&#x2F;docs&#x2F;BlockLanguageSpec.html</a>
basementcatover 5 years ago
There are a variety of ways to use lambdas in C, each uniquely horrifying.<p><a href="https:&#x2F;&#x2F;codegolf.stackexchange.com&#x2F;questions&#x2F;2203&#x2F;tips-for-golfing-in-c&#x2F;104999#104999" rel="nofollow">https:&#x2F;&#x2F;codegolf.stackexchange.com&#x2F;questions&#x2F;2203&#x2F;tips-for-g...</a>
评论 #20947191 未加载
评论 #20945466 未加载
mpfundsteinover 5 years ago
I still wonder why C still does’t have lambas implemented by standard. I understand its a quite slow moving language but it would make programming in it mich nicer (see C++11)<p>Are there anh underlying ‘issues’ with lambdas, I wonder?
评论 #20946277 未加载
评论 #20944445 未加载
评论 #20944373 未加载
评论 #20944329 未加载
lgeorgetover 5 years ago
&gt; However, it seems like if it compiles it ought to work and — mostly — it does.<p>I&#x27;m taking this out of context of course but that looks like a very dangerous assumption to make...