Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is initialization an assignment expression?

I found this paragraph in C17(6.7.9 #1):

initializer:
    assignment-expression
    { initializer-list }
    { initializer-list , }
initializer-list:
    designation{opt} initializer
    initializer-list , designation{opt} initializer
designation:
    designator-list =
designator-list:
    designator
    designator-list designator
designator:
    [ constant-expression ]
    . identifier

Does this mean that the initializer expands to an assignment expression and we can use it this way?:

#include <stdio.h>
int main(void)
{
    if((int n = 9) == 9){}
    
    return 0;
}
  1. If not, why not?

  2. Why is initialization not an expression?

  3. Why is initialization referred to as a declaration?

  4. Why is the assignment expression not an initializer?

  5. What is a declarator?

I'm sorry for such indiscreet questions.I'm new to C and I just want to know.

And if it's not difficult for you, could you provide the relevant paragraphs from the C Standard?

Thank you very much!

like image 996
ALICEZzz Avatar asked Jul 25 '26 02:07

ALICEZzz


2 Answers

The initializer is part of a declaration. E.g. the following is a simple declaration:

int n = 1;

Within this declaration, the expression 1 is the initializer. You can find this in the syntax diagram at the beginning of section 6.7.

In a declaration, the initialization is optional; you can write:

int n;

to declare the variable without giving it an initial value (there are some contexts where there's a default initial value, such as global variables being zero-initialized).

A declaration is a statement, but it's not an expression, so it can't be used where an expression is required. So you can't write

i = (int n = 1);

and you can't use it in your if expression.

There are different types of initializations. In the above example, we're initializing a single value, so the initialization is an expression. But we can also initialize aggregates (arrays and structures), and in that case we use initialization lists:

int a[] = {1, 2, 3};
struct {
    int x;
    char c;
} foo = {1, 'a'};

So an expression is one kind of initializer, but an initializer isn't necessarily an expression (an initialization list is not an expression, although it contains expressions).

A declarator is the part of a declaration that indicates what is being declared. E.g. in

int n = 1;

n is the declarator. You can see the full specification of declarators in section 6.7.6 (it's a bit complex because declarators can be nested).

like image 186
Barmar Avatar answered Jul 28 '26 14:07

Barmar


Does this mean that the initializer expands to an assignment expression and we can use it this way?

It is actually the opposite: The grammar says you can have an assignment inside an initialization, not an initialization inside an assignment.

If not, why not?

In the grammar rules, the : in A: B means A can be a B.

Why is initialization not an expression?

In the grammar, initializer appears in init-declarator (that is, initializer appears on the right side of a : rule with init-declarator on the left), which appears in init-declarator-list, which appears in declaration. None of those appear in the grammar for expression, except a compound literal has initializers. A compound literal is something you can use in an expression, but it will not be declaring any variables.

Why is initialization referred to as a declaration?

Where do you see that?

Why is the assignment expression not an initializer?

An assignment expression can be an initializer. For example, in int a, b = a = 3;, the a = 3 is an assignment expression. Its value is 3, so b is initialized to 3.

What is a declarator?

A declarator is the part of a declaration that goes where the D is here: Type D;, excluding the = initializer that could be there with the D. That is, you could have int foo = 3;, but only the foo would be the declarator. (There can be additional parts to Type and can be multiple declarators, in a list, but I have used this simplified example for illustration.) That D can be a name (int foo;), an array declarator (int foo[3];), a pointer declarator (int *foo;), a function declarator (int foo(char, float);), or a parenthesized declarator (int (*foo); or int (foo);), and it can be combinations of those (int *foo[3];, int (*foo)[3]). (There can be additional parts of those declarators, such as int foo[const 3];, which I do not cover further here.)

like image 32
Eric Postpischil Avatar answered Jul 28 '26 16:07

Eric Postpischil



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!