[HN Gopher] C Gibberish to English
       ___________________________________________________________________
        
       C Gibberish to English
        
       Author : warkanlock
       Score  : 54 points
       Date   : 2024-11-11 20:22 UTC (3 days ago)
        
 (HTM) web link (cdecl.org)
 (TXT) w3m dump (cdecl.org)
        
       | ngcc_hk wrote:
       | May need some bracket first then English.
        
       | pavlov wrote:
       | Use typedef?
       | 
       | Granted, the function pointer syntax is forever confusing (to me
       | anyway). The rest is easily tackled by naming things.
       | 
       | Even for function pointers, it's just one lookup and then you can
       | copy-paste the typedef for any other function pointer types in
       | the project.
        
         | sebstefan wrote:
         | >Use typedef?
         | 
         | What if you're given somebody else's code and you need to
         | understand it to put a typedef there
        
           | DaiPlusPlus wrote:
           | Welp, if it's that bad then shrug and use a #define
           | 
           | (Yes, this is a joke)
        
           | jacoblambda wrote:
           | The trick is to just assert equal types. Most compilers have
           | extensions that allow you to easily compare type equality
           | (and C23 actually standardizes the `typeof()` operator).
           | 
           | So you basically take your ugly type, put it in a #define and
           | then create a static assertion that matches the type against
           | said ugly type.
           | 
           | Now the compiler will throw a shit fit if the types don't
           | match. Have fun breaking the type up into smaller pieces
           | until you have something legible.
        
         | dapperdrake wrote:
         | Reading C Type Declarations:
         | http://unixwiz.net/techtips/reading-cdecl.html
         | 
         | ( _NOT_ the author. It simply helped me.)
        
         | khrbtxyz wrote:
         | Function typedefs make this less confusing by removing awkward
         | parentheses. e.g.                 typedef int
         | read_block_fn(void *context, u8 *buf, unsigned int block,
         | size_t len);
         | 
         | https://github.com/torvalds/linux/blob/0a9b9d17f3a781dea03ba...
        
       | card_zero wrote:
       | Is there a language that's substantially free of gibberish?
        
         | marginalia_nu wrote:
         | Yeah sure, COBOL is great in that regard. Basically reads as
         | English.
        
         | pwilson7 wrote:
         | nope
        
         | pjmlp wrote:
         | Those of Algol/Wirth linage, or influenced by then.
         | 
         | Then again people complain that they are too verbose, and they
         | rather write in hieroglyph friendly languages.
        
           | Joker_vD wrote:
           | Compare                  char (*(*x())[5])();
           | 
           | and                  var x: pointer to func() pointer to
           | array[5] of pointer to func() char;
           | 
           | or if you wish to replace some keywords with glyphs:
           | var x: ^func() ^[5] ^func() char;
           | 
           | And it's always a nice puzzle for the reader to explain why
           | there are three "pointer" in cdecl output and three carets in
           | the ALGOL-like declaration, but only two asterisks in the C
           | declaration.
        
             | trealira wrote:
             | In this case, the C declaration doesn't match the other
             | two. The variable x is a function that returns a pointer to
             | an array of 5 pointers to functions returning char. Indeed,
             | that's what cdecl.org says:                 declare x as
             | function returning pointer to array 5 of pointer to
             | function returning char
             | 
             | Using the notation you did, that would be:
             | var x: func() ^[5] ^func() char
             | 
             | There are only two arrows there now.
             | 
             | If you wanted a pointer to a function like this, you would
             | need a third asterisk in the declaration:
             | char (*(*(*x)())[5])();
        
               | Joker_vD wrote:
               | Oh, good catch, thank you! But I remember an example with
               | some other tricky C expression/type declarator where the
               | number of actual dereferences differed from the amount of
               | asterisks in the code.
               | 
               | > Using the notation you did, that would be:
               | 
               | Well, it'd be                   func x() ^[5] ^func()
               | char; ...
               | 
               | because it's a function declaration, after all, not a
               | variable.
        
         | dogleash wrote:
         | Depends on the features you want.
        
         | chongli wrote:
         | Racket Beginning Student [1] language.
         | 
         | [1] https://docs.racket-lang.org/htdp-langs/beginner.html
        
         | unrealhoang wrote:
         | for declaring function pointer?
         | 
         | Any language with type after name :                   // c
         | char (*(*x[3])())[5];         // golang         var x [3]func()
         | *[5]byte
        
         | sitzkrieg wrote:
         | forth will contain as much gibberish as you put into it
        
       | lynx23 wrote:
       | Why is it that the first thing I try tends to uncover
       | shortcomings?
       | 
       | typedef uint64_t qbb_t
       | __attribute__((vector_size(sizeof(uint64_t) * 4)))
       | 
       | Syntax error
       | 
       | OK, its an extension, meh.
        
         | veltas wrote:
         | Looking at the project issues, it seems it supports only
         | 1989-era C, and some Apple stuff, before you even get to
         | attributes.
        
       | djmips wrote:
       | Is this largely supplanted by LLMs?
        
         | veltas wrote:
         | The difference is I trust this website, and wouldn't trust an
         | LLM.
        
         | andix wrote:
         | Probably.
         | 
         | Output for the example I got on opening the website:
         | char (*(*x())[5])()
         | 
         | cdecl.org: declare x as function returning pointer to array 5
         | of pointer to function returning char
         | 
         | ChatGPT: x is a function that, when called, gives us access to
         | 5 functions that each return a character. (TL;DR, it gave a
         | full explanation too)
         | 
         | Like mentioned before the error rate of LLMs is probably much
         | higher on complex expressions.
        
         | marginalia_nu wrote:
         | LLMs are mostly correct with regards to this stuff.
         | 
         | cdecl is always correct with regards to this stuff.
         | 
         | I don't know why you'd choose the former.
        
           | Y_Y wrote:
           | Because if you don't do things exactly the way cdecl wants
           | you get a Syntax Error
        
             | marginalia_nu wrote:
             | Wouldn't any explanation given, apart from syntax error, be
             | wrong in the case you provide it with an invalid syntax?
        
               | Y_Y wrote:
               | I was thinking of the issue of going from English to C.
               | Even when you out in malformed C it's nice to get either
               | a compiler error which explains the problem, or even
               | better an LLM that can suggest how to fix it.
        
       | makach wrote:
       | I can read that.
       | 
       | I don't think it is gibberish. It's code and in order to read
       | that code you need to understand the language, and to understand
       | language you need learning and experience.
       | 
       | Maybe it can be useful for learning, but if you have to use such
       | tool, I suspect you won't understand it anyway - so in a way it
       | is more a gibberish-to-gibberish translator.
        
         | tuveson wrote:
         | I disagree. The conventions for declaring arrays, pointers, and
         | function pointers are all idiosyncratic. In C, the type is
         | always to the left of the variable being declared. Except for
         | arrays, which have part of the declaration to the right. And
         | except for pointers, which need to be affixed to every item if
         | there are multiple declarations. And except for function
         | pointers where you need to wrap the variable name like (*name).
         | Individually I can wrap my head around these exceptions, but
         | putting all of them together, it's just hard to read.
        
         | Brian_K_White wrote:
         | It takes a pretty smart person to do that. Which is pretty
         | confusing.
         | 
         | How can such a smart person not not understand how all things
         | that are possible are not all equally good?
         | 
         | The fact that both the compiler and you can parse that doesn't
         | make it a good way to document or convey meaning or intent.
         | 
         | C is chock full of inconsistencies and ambiguities that are
         | only disambiguated by essentially being a human compiler and
         | maintaining the same parsing state-machine manually in your
         | head to know what any given "(" actually means or does. As a
         | self-proclaimed fluent C linguist, you know this better than
         | most.
         | 
         | All coding involves that of course but all implimentations are
         | not equally unhelpful.
         | 
         | The cpu and some people can read the binary itself. They just
         | need to know the cpu's opcodes, documented right in the
         | datasheet that anyone can read.
        
       | elcritch wrote:
       | Handy site!
       | 
       | Next I want one to explain some of Rust's more cryptic pointer
       | gibberish. Usually I just hit "use suggested fix X" until the
       | compiler's happy.
        
         | Thiez wrote:
         | Rust isn't so bad, is it? The example of `char ( _(_
         | x[3])())[5]` would translate to `[fn() -> [fn() -> u8; 5]; 3]`.
         | It's inherently an ugly type, but I think it's easier to read
         | than the C version.
        
       | ashleyn wrote:
       | char (*(*x[3])())[5]
       | 
       | I'm more of the mindset that writing something like this is
       | probably a code smell to begin with. Is there any reason I'm not
       | thinking of right now, that this couldn't be typedef'd and
       | refactored into something far more readable?
       | 
       | C gets a lot of blame for pointer gibberish like this but quite
       | honestly you can write gibberish in any language. I don't see any
       | fundamental or technical reason you couldn't write clean,
       | readable C.
        
         | jacoblambda wrote:
         | the function signature certainly should be type def-ed. i.e.
         | typedef char (*fn())[5];
         | 
         | and then you have the original as                   fn x [3];
        
           | fsckboy wrote:
           | I don't keep up with the latest C shenanigans, cuz I like C
           | the way it was, but have they change something where "pointer
           | to an array[5]" is a meaningful distinction to draw?
           | 
           | I mean, "a pointer to an array of X" is simply "a pointer to
           | X" and using hungarian notation, you can encode the knowledge
           | "this pointer can be incremented" into its name.
           | 
           | and typedef'ing *function declarations? who has families of
           | functions with the same type signatures that they want to
           | point to?
        
             | jacoblambda wrote:
             | > but have they change something where "pointer to an
             | array[5]" is a meaningful distinction to draw
             | 
             | This has been a meaningful distinction since at least C99.
             | 
             | > "a pointer to an array of X" is simply "a pointer to X"
             | 
             | They aren't actually the same. The former can be decayed
             | into the latter but they aren't actually equivalent and
             | you'll get type mismatches if you try to treat them as the
             | same thing.
             | 
             | > who has families of functions with the same type
             | signatures that they want to point to
             | 
             | An example is callbacks or handlers for responding to
             | interrupt requests. A lot of hardware interface code relies
             | on typedef-ed function decls because very often you are
             | passing user side functions through your interface so that
             | you can stash those function pointers somewhere and invoke
             | them when some event occurs.
        
             | kelnos wrote:
             | > _" a pointer to an array of X" is simply "a pointer to
             | X"_
             | 
             | I don't believe these two are the same. An "array of X"
             | indeed decays to a "pointer to X". But a "pointer to an
             | array of X" is something else. E.g.                   int
             | foo[3];  // array of int         int *foo;    // pointer to
             | int         int *foo[3]; // pointer to array of int
             | 
             | Perhaps the first two are what you mean, though, and this
             | is just a terminology issue.
        
               | fsckboy wrote:
               | int *foo[3]; // pointer to array of int
               | 
               | that's an array of 3 pointers to ints. if you pass foo as
               | an argument you get a pointer to a pointer to an int
               | (with knowledge if you can hang onto it that there are
               | more pointers to ints lined up in memory)
        
         | theanonymousone wrote:
         | I'm not a C programmer but your comment reminds me of all the
         | lame jokes people make about the German language.
        
       | vzaliva wrote:
       | Is it just a web wrapper around good old `cdecl` command? Or it
       | does something different/better?
        
       ___________________________________________________________________
       (page generated 2024-11-14 23:02 UTC)