Concerning OP's first sample code:
int a;
(a) = 3;
This is a declaration (1st line), followed by an assignment expression (2nd line).
The second sample code:
(int a) = 3; /* COMPILER ERROR */
is illegal but for further explanations I change this into:
int a = 3;
which is a definition – a declaration with initialization.
Assignment and declaration with initialization are something different although they look very similar (probably intentionally). (I got the feeling the OP is not aware about this, so I elaborate a bit.)
A complete C grammar can be found ANSI C Yacc grammar. (This is really old but I believe for what I want to explain it's sufficient.)
Rules applied to (a) = 3;
:
for 3
: primary_expression : CONSTANT
for a
: primary_expression : IDENTIFIER
for (a)
: primary_expression : '(' expression ')'
for =
: assignment_operator : '='
for (a) = 3
: assignment_expression : unary_expression assignment_operator assignment_expression
(where the assignment_expression
on right-hand side is resolved in multiple steps to a primary_expression
).
Rules applied to int a = 3;
for int
: type_specifier : INT
for a
: direct_declarator : IDENTIFIER`
for int a = 3;
: (this becomes complicated)
declaration : declaration_specifiers init_declarator_list ';'
declaration_specifiers : type_specifier
init_declarator_list : init_declarator
init_declarator : declarator '=' initializer
initializer : assignment_expression
Putting this together, it comes out that the following would be valid:
int b, a = (b) = 5;
/* ^ ^
* | +--- assignment operator
* +--------- initializer
*/
but there is simply nothing in the grammar to resolve
(int a) = 3; /* COMPILER ERROR */
May be, it's worth to mention that there is a similar question
SO: Initialization vs Assignment in C.