Lies in education [was Re: The "loop and a half"]
On 11/10/2017 19:30, Chris Angelico wrote:
> On Thu, Oct 12, 2017 at 5:22 AM, Grant Edwards
>> The easiest way to make stuff like that readable is to unroll them
>> into a sequence of typedefs. But, a lot of people never really
>> learn how to do that...
> The most complexity you'll usually see is a function that
> accepts/returns a pointer, and those generally should be typedef'd.
> But even if not, they're still not anything like as bad as the
> mythical examples that get touted as "why C is bad" or "why variable
> declarations are bad" or "why type declarations are bad".
IME typedefs can make things worse, especially if used even for basic
types. Then you spend your time tracing back typedefs to see what they
mean (was it a char, or struct or what?).
C can combine the abstruseness of its type declarations, overuse of
macros, and overuse of #if/ifdef blocks to render a lot of code a
complete nightmare to try and understand. Or debug. Or maintain. Or
port. Or implement (if testing a compiler).
I've looked at some of my generated C code, and here's one common
example, not a complex type:
tokenrec * (*)
But I couldn't figure that out from the top of my head. Bear in mind
this was in a parameter list that can change the meaning of . I looked
at the original source and that type is written like this:
ref  ref tokenrec
'ref' means 'pointer to', and it can also be written like this:
pointer  pointer tokenrec
In English, 'pointer to array of pointer to tokenrec'. See how the
source language corresponds almost exactly to the English, and both are
written left to right. Now go back and look at the C version - where do
you even start? Are those parentheses significant? (I've no idea.)
The most complex of /my/ types to appear in generated C is probably
this, used as a cast in this assignment:
pcptr = (*(int64 * (**) (void))pcptr)();
(Original source is this:
pcptr := ref ref function=>ref int64(pcptr)^^()
In English, the cast is 'pointer to pointer to function returning
pointer to int64'.
The line includes two dereferences (^^) which /I think/ account for two
of the "*" in the C version. Which * are dereferences, and which are
part of the type, or indeed whether only one * is the dereference, I
have absolutely no idea. Great language...)