In my view, a "user-oriented" declaration of an array of pointers would look like `pointer[10] of int`, and not `int *arr[10]`.
This is pretty close to Pascal syntax already: `array[0..9] of ^Integer`, where ^ is pronounced 'pointer to'.
Pascal is a language that is genuinely easy to parse; it's designed to be LL(1). C is not; in particular, typedefs effectively introduce keywords, and the easiest way to parse C is to inform the tokenizer about typedefs as they're found so the parser can disambiguate things like `a (b);`; this looks simultaneously like declaring a variable and calling a function, depending on the type of 'a'.
(they don't look the same, but you can use either to define record/structure types or enums, for example)
int main()
{
foo(bar);
foo * bar;
}
If foo is a typedef, these are variable declarations, otherwise the first is a function call and the second multiplication (syntactically). These are different kinds of things that would normally be up to the parser to figure out (rather than semantic analysis later). These are well-known ambiguities relating to typedefs in C (well-known to compiler authors, at any rate).The situation doesn't come up in Pascal because variables go in the var block (starting with the 'var' keyword) and functions and procedures both start with keywords ('function' and 'procedure').
It never occurred to me to put variables names inside parens in a declaration when I did C, though. But OF COURSE it's legal obfuscation.
As stated elsewhere, I don't know why C had to screw up Algol's syntax so badly. I guess K&R liked curly braces much more than BEGIN/END, and why stop there, once you get going. Maybe somebody had a love affair with APL???
Using the same precedence and associativity in declarations and normal expressions doesn't really help the compiler writer though, so I'm not sure how this supports your point. If anything, it complicates the parser by making it harder to decide if a given sequence of tokens is a declaration or an expression (e.g. the classic "a * b;" problem).
> In my view, a "user-oriented" declaration of an array of pointers would look like `pointer[10] of int`, and not `int *arr[10]`.
It sounds like you're saying that C's type syntax isn't easier to read than other, similar, possible syntaxes. On that, I completely agree (in fact, I think C's type syntax is horrendous). However, that's orthogonal to the issue of Dennis Ritchie's original intent when designing C. From his writings at least, it seems like he wanted to make it easy for the programmer to reason about the syntax and I'd even argue that he took steps to complicate the compiler to accommodate his chosen syntax. I'd also argue that he failed horribly in accomplishing his intention and the syntax you're describing would have been much easier to read.
Not rocket science, obviously, but the original statement was that C types were designed to be easy to parse, which clearly isn't true. If the types were prefix or postfix, it'd be trivial to build the trees in a recursive descent parser.
And remember declarations can be arbitrarily complex. How do you declare a pointer to arrays of pointers to pointers to arrays? In free prose.
Err, I would agree with the statement that the syntax of C (mostly) favors the compiler writer, but "declarations mirror use" is decidedly not a good example for a couple of reasons:
[1] Compare https://www.lysator.liu.se/c/ANSI-C-grammar-y.html to [2].[2] http://www.csci.csusb.edu/dick/samples/algol60.syntax.html#5...
[3] "Analogical reasoning led to a declaration syntax for names mirroring that of the expression syntax in which the names typically appear...In all these cases the declaration of a variable resembles its usage in an expression whose type is the one named at the head of the declaration." from http://www.jslint.com/chistory.html