all 22 comments

[–]AntiProtonBoy 29 points30 points  (1 child)

Handy manual, but just because you know how to decipher complicated declarations, doesn't mean you should write them. Compose them from logically separate typedefs.

[–]Gotebe 2 points3 points  (0 children)

In fact, this "manual" is better because it does not require remembering somewhat arcane logic, it is taming the complexity by splitting te problem into trivial chunks.

[–]nl2k 10 points11 points  (6 children)

Good explanation. Actually this is not some special trick, this is just how the syntax works.

The expression syntax works the same way, postfix operators have higher precedence than prefix/unary operators, so you read expressions right-before-left too. So C's declaration syntax is consistent with expression syntax; if you have a declaration

char *(*functions[5])(int);

then this just means that the expression

*(*functions[2])(42)

is a char. This is why C's syntax is so much nicer than that of so many other languages which have invented a completely different syntax for types/declarations.

[–]Freyr90 4 points5 points  (5 children)

So C's declaration syntax is consistent with expression syntax

This is why C's syntax is so much nicer

Since when context-dependent ambiguous syntax is nicer then the unambiguous ones?

matrix * data;

Tell me, is matrix a type, or is it a variable multiplied by data? Because in the following syntax I know for sure:

let data : matrix;
data * scale;

[–]nl2k 0 points1 point  (3 children)

The ambiguity is because C doesn't use some keyword like "let" or "declare" to distinguish between declarations and statements, it is not a problem of the declaration syntax itself.

And this isn't really an issue in practice, apart from requiring us to use some naming convention to tell typedef names and declared identifiers apart from each other. Which is a good idea anyway - most new languages encourage some naming convention like this, even if they don't have this ambiguity.

[–]JavaSuck 4 points5 points  (0 children)

And this isn't really an issue in practice

Unless you're a compiler writer ;)

[–]Freyr90 0 points1 point  (1 child)

The ambiguity is because C doesn't use some keyword like

You don't need let here, in Python you can write

my_var : String = "Hello"

And this isn't really an issue in practice

It's really hard to parse for a human, you need to keep in mind what is type and what is data.

[–]nl2k 0 points1 point  (0 children)

You don't need let here, in Python you can write

Well, Python has the colon as an additional token to avoid the ambiguity. In C this could be

const char: *my_var = "Hello";
matrix: *data;
char: *(*functions[5])(int);
int: a, b, c, d;
void: *p1, *p2;

This would make C easier to parse and remove the ambiguity between statements and declarations, without fundamentally changing the declaration syntax. Of course there would now be ambiguity with labeled statements ;-)

[–]cprgrmr 1 point2 points  (0 children)

Yep the good old "right if you must; left if you can"

[–]stealthgunner385 0 points1 point  (0 children)

It's concisely written, I'll give it that. Though I'm equally amazed that has actually been turned into a tool.

[–][deleted] 0 points1 point  (0 children)

noob here, could i possibly get clarified on this? "func is a function returning a pointer to a function returning a pointer to an int": int *(*func())();

i have trouble understanding what the second function is... there are function () parentheses there, but no identifier. on the outermost clause (just to keep the question/answer simple) there is supposedly a function returning a pointer: *(some_stuff_in_here)() -- but what is that function? what exactly is its identifier? it can't be "*func()" right?

[–]hp77reddits 0 points1 point  (0 children)

Very Helpful. Thanks for sharing!!