The new c++ alt function syntax talked about here:
<a href="https://blog.petrzemek.net/2017/01/17/pros-and-cons-of-alternative-function-syntax-in-cpp/" rel="nofollow">https://blog.petrzemek.net/2017/01/17/pros-and-cons-of-alter...</a><p>mentions replacing function declarations for<p><pre><code> void (*get_func_on(int i))(int);
</code></pre>
with<p><pre><code> auto get_func_on(int i) -> void (*)(int);
</code></pre>
which looks a lot more readable to me.
The trick to reading crazy C declarations is learning the "spiral rule": <a href="http://c-faq.com/decl/spiral.anderson.html" rel="nofollow">http://c-faq.com/decl/spiral.anderson.html</a> (here are more examples, with nicer formatting: <a href="http://www.unixwiz.net/techtips/reading-cdecl.html" rel="nofollow">http://www.unixwiz.net/techtips/reading-cdecl.html</a>)
For anyone unable or unwilling to access that domain name for work purposes or filtering purposes, the linked page lists this alternative:
<a href="http://goshdarnfunctionpointers.com/" rel="nofollow">http://goshdarnfunctionpointers.com/</a>
The easiest and best way to learn the syntax is to not memorise specific cases but the grammar itself, which IMHO is no more difficult than the existing concept of operator precedence. Everyone using C should hopefully already know that multiplication has higher precedence than addition, so likewise function call (and array subscripting) has higher precedence than pointer dereference. Thus this table should make it clear that combining the two operators creates pointer-to-function:<p><pre><code> T x; T *y;
T f(); T (*g)();
T pointer to T
function returning T pointer to function returning T
</code></pre>
and the alternative, T <i>h(); , is parsed as T </i>(h()); and thus becomes "function returning pointer to T".<p>The apparent struggle I see with this syntax has always somewhat puzzled me, because I don't see the same level of complaints about e.g. arithmetic expressions (like 6+3*4/(2+1)) which are parsed with precedence in much the same way. K&R even has a section on writing a parser that recognises this syntax, so I suspect it's really not that hard, but the perception spread by those who didn't learn the syntax but only memorised the "easy cases" is making it appear more difficult than it really is.
Every time I have to deal with the declarator syntax in C or C++, I can't help but ponder what K&R were thinking when they designed this. It's not like there weren't other languages back then with a saner approach.<p>It looks like what they did was take the syntax from B:<p><pre><code> auto x[10];
</code></pre>
and generalize it such that the type name ended up before the variable name, as in Algol. But in B this worked much better, because it didn't have array <i>types</i> (or pointer types, or function types) - everything was a machine word. So [] in a variable declaration was just to allocate memory to which the variable would refer; the variable itself would still be a word. When they made [] part of the type, and added pointers and function types, the result was a mess.
Or if one doesn't have cdecl installed there's an online version[1] which has proven as a useful check on several occasions<p>[1] <a href="http://cdecl.org/" rel="nofollow">http://cdecl.org/</a>
This is one of those cases where I prefer C++<p><pre><code> template <typename Func> using function_ptr = add_pointer_t<Func>;
</code></pre>
and now declarations are a bit more sane:<p><pre><code> void foo(function_ptr<void (int)> callback);</code></pre>
I never got used to having variables sandwiched inside a type. I know I am not supposed to suggest out-of-the-box, but why can't we add a new syntax, e.g.:<p><pre><code> return_type Fn(parameters) var;
typedef return_type Fn(parameters) TypeName;
</code></pre>
where Fn is a new keyword -- or not, if compiler understands dummy syntax -- (I would suggest &lambda; when using greek letters in code become norm).<p>It simplifies the C syntax a lot IMHO.<p>PS: now I am out-of-the-box, maybe this is better:<p><pre><code> Fn{return_type, param1, param2} *var;</code></pre>