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.

Cdecl – Turns English phrases into C declarations

150 pointsby dammitcoetzeeover 6 years ago

13 comments

jcranmerover 6 years ago
Here&#x27;s an easy way to understand how these things work: in C, the type of a pointer&#x2F;function&#x2F;array mess is declared by how it&#x27;s used. For a declaration like &quot;int ( * ( * foo)(void))[3]&quot;, you can read it as &quot;for a variable foo, after computing the expression ( * ( * foo)(void))[3], the result is an int.&quot;<p>So one way to read C &quot;gibberish&quot; is to ignore the type at the beginning and parse the rest as an expression like a normal parse tree. First we take foo. Then we dereference it (so foo is a pointer). Next we call it as a function with no arguments (so foo is a pointer to a function that takes no arguments). Next, we dereference it again. Then we index into the result as an array. Finally, we reach the end, so we look at what the declared type and find that this type is an int. So foo is a pointer to a function that takes no arguments and returns a pointer to an array of 3 ints.<p>You can also use this to go backwards. What&#x27;s the syntax for a function that takes an integer argument returns a pointer to an array of function pointers taking no arguments and returning integers? Well, we want to take foo, call it, dereference it, then index into an array, then dereference it again, then call it again, then return an int. Or int (* (* (foo)(int))[5])(void).
评论 #18843730 未加载
评论 #18844537 未加载
评论 #18843671 未加载
评论 #18851228 未加载
评论 #18851171 未加载
评论 #18843286 未加载
ridiculous_fishover 6 years ago
Hey, this is my site, first published 2009! This is the venerable cdecl enhanced with blocks support.<p>It used to be a shared host with a PHP script shelling out to the cdecl executable, written in K&amp;R C. Now it&#x27;s that same executable running on AWS Lambda.<p>Yes Lambda really will run arbitrary ELF binaries.
评论 #18844195 未加载
评论 #18843960 未加载
评论 #18843850 未加载
saagarjhaover 6 years ago
For all of its simplicity, the syntax for complex types in C is pretty horrible. Yes, I know the &quot;inside out&quot; rule, and can usually read these, but that doesn&#x27;t make it any less bad.
TorKlingbergover 6 years ago
I&#x27;ve been a professional C programmer for years, but I rarely find cdecl useful (command line or website). Not because complex C declarations are intuitive to me, but because cdecl fails on any unknown types. Real world C code is full of typedefs.
评论 #18843846 未加载
nurettinover 6 years ago
Back in early 2000s, we had bots on IRC doing this. My favorite technique was to pass the type to a template function, assign it to an integer and then parse the compile time error produced by gcc to extract the type.
Eli_Pover 6 years ago
If I recall correctly, this one came as an exercise in Knuth&#x27;s book of C programming, ibidem were C declarations and priorities explained.
评论 #18844557 未加载
pkayeover 6 years ago
Its better to create a series of typedef and build up the declaration. Most of the time you need those sub typedef anyway.
评论 #18843589 未加载
valerijover 6 years ago
on topic of function pointers, is there a template to turn<p><pre><code> std::funtion&lt;foo(bar, baz)&gt; </code></pre> into<p><pre><code> foo(*)(bar, baz) ?</code></pre>
评论 #18849581 未加载
meyover 6 years ago
Need this for bash and by proxy regex.
评论 #18843244 未加载
评论 #18844299 未加载
SidiousLover 6 years ago
The actual principle behind the C type declarations is &quot;declaration follows use&quot;. Let me explain what this means. Take this declaration<p><pre><code> int *pi; </code></pre> Means that when I dereference the variable pi, I get an int. This also explains why<p><pre><code> int *pi, i; </code></pre> declares `pi` as a pointer to `int` and `i` as an `int`. From this point of view it makes sense stylistically to put * near the variable.<p>Declaration of array types is similar. For example,<p><pre><code> int arr[10]; </code></pre> means that when I take an element of `arr`, I obtain an `int`. Hence, `arr` is an array of ints.<p>Pointers to functions work the same way. For example,<p><pre><code> int (*f)(char, double); </code></pre> means that if I dereference the variable `f` and I evaluate it on a `char` and on a `double`, then I get an `int`. Hence, the type of `f` is &quot;pointer to function which takes as arguments a char and a double and returns an int&quot;.
skookumchuckover 6 years ago
The way to make complex C declarations legible is to use typedefs for the subtypes (like function pointers).
Jerry2over 6 years ago
Tried it on this <i>gibberish</i> but it complains about syntax:<p>((void(*)(void))0)();
评论 #18843742 未加载
评论 #18843248 未加载
评论 #18844251 未加载
unnouinceputover 6 years ago
tried: declare xxx as integer pointer to array of string equal to &quot;mumu&quot; and &quot;kaka&quot;<p>got: bad character &#x27;&quot;&#x27;...apostrophe instead of double quote has the same result...well, I guess I expected too much
评论 #18846184 未加载