| ▲ | pillmillipedes an hour ago | |
I'll try to do the first one since I think it's the most illustrative:
(1) is equivalent to "typedef long* $(void*, ...)". '$' is the name of the defined function type.it's obfuscated as follows: - typedef is a specifier and can go on either side of the type, same as int const/const int - [[ ]] is an empty list of attributes - "void*($)" is an argument named '$' of type void*, but parameter names are ignored in declarations. - you can put parens in declarations since sometimes you need to group prefixes and postfixes in a different order - dollar signs in names are allowed in many c compilers (and some other c-like languages) - "..." are variadic arguments. puts doesn't have those, but the first argument uses the same register either way so it happens to work out in this case (4) declares a function named '$' of type '$', shadowing the type, and links it to the assembly label "puts". calling $ calls puts. normally it looks like `int call_foo(void) asm("foo");` (5) is parsed as: "label $: address-of-label $ and function $ called on str. the address of a label is truthy, so the function also gets called. unary && looks for the argument in the label namespace, but other operators don't, so the two dollars refer to different things. that's about it. if you're familiar with the c standard and some common gnu extentions, you can deconstruct the examples into their basic elements easily enough | ||