3 ms·
> Do you have a link to the actual grammar and production rules that apply to all cases ? A google search returns that Annex A in the ISO standard has somethin
by jstimpfle 7y ago
> Do you have a link to the actual grammar and production rules that apply to all cases ?
A google search returns that Annex A in the ISO standard has something like a grammar. Here is a link to an unoffical version of the standard: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf . However, this is not the right place to look for if you just want to understand the simple principle behind declarations, because the purity of declaration syntax has been considerably diluted in the last decades. So, only look in the standard if you are in good psychological health, and need to implement a production-grade C compiler. Also, note that grammars are overrated and tend to make things more complex than they really are. They are often too theoretical of a construct to be applicable, and that is certainly true for a language like C.
Instead, I recommend you to read the idea from the horse's mouth, here is Dennis Ritchie talking about it: https://www.bell-labs.com/usr/dmr/www/chist.html https://www.bell-labs.com/usr/dmr/www/chist.html
> I don't see a "type name followed by an expression and a semicolon", but rather the grammar "TYPE_NAME NAME = EXPR;".
Let's ignore the optional equal sign + initializer expression, and just focus on declarations without initializers. The syntax is (as I said) "TYPE_NAME EXPR;" where EXPR is an expression that makes use of the newly-declared variable.
> (e.g. a function pointer won't work)
Not sure what you mean by "function pointer", but I'm pretty sure it's not a type name in the way I mean it. Here is how to look at your examples:
void (*foo)(int) = expr;
^^^^^^ (optional) initializer
^^^^^^^^^^^ expression (originally it was (*foo)(x),
but as I said nowadays there are
type specifiers in the list which
is a little inconsistent.)
^^^^ type name
int (*foo)[N] = expr;
^^^^^^ (optional) initializer
^^^^^^^^ expression
^^^ type name
Basically, the first example says "(* foo)(int) is a void", so you can conclude that foo is a pointer to a function that takes an int and returns a void.
The second example says "(* foo)[N] is an int" so you can conclude that foo is a pointer to an array of N ints.