2 ms·
The “spiral rule” is just an approximation of the actual rule as defined in the standard: declaration follows usage. Even with typedefs, that declaration means
by evincarofautumn 10y ago
The “spiral rule” is just an approximation of the actual rule as defined in the standard: declaration follows usage.
Even with typedefs, that declaration means “when you call baz with a bing and a pointer (named bratz) to a function of type boff(biff), then you get back a pointer to a function of type foo(buff).”
It’s an extremely concise notation for expressing type information without (much) special type syntax, and I think it’s quite elegant in that way.
- lisper 10y agoI'm impressed. How did you know where to start?
- evincarofautumn 10y agoIn C, the statement “type declarator;” is an assertion that “declarator” has the type “type”. In other words, if you read “declarator” as an expression (more or less), then it should have the type “type”. So here: foo (*baz(bing, boff (*bratz)(biff)))(buff); “foo” is the type, and the rest is the declarator. Then you just break it down according to the usual precedence rules: baz(…) “baz” is a function… baz(bing, …) …which takes a “bing”, and… *bratz …a pointer (arbitrarily named “bratz”)… (*bratz)(biff) …to a function which takes a “biff”… boff(*bratz)(biff) …and returns a “boff”… *baz(…) …and “baz” returns a pointer… (*baz(…))(buff) …to a function taking a “buff”… foo (*baz(…))(buff) …and returning a “foo”. With typedefs for function pointer types: typedef boff (*bratz_t)(biff); typedef foo (*baz_ret_t)(buff); baz_ret_t baz(bing, bratz_t); Or for function types: typedef boff bratz_t(biff); typedef foo baz_ret_t(buff); baz_ret_t *baz(bing, bratz_t *);