Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Declarators semantics in C99

Tags:

c

c99

c11

According to the ISO/IEC 9899:1999 6.7.5 §2,

Each declarator declares one identifier, and asserts that when an operand of the same form as the declarator appears in an expression, it designates a function or object with the scope, storage duration, and type indicated by the declaration specifiers.

I have no idea why an expression suddenly shows up in the declarators semantics. Would you give me some examples that can help me understand the meaning?

like image 567
김단영 Avatar asked Sep 26 '14 16:09

김단영


2 Answers

Say you declare:

static int const i, j, k;

That is same as:

static int const i;
static int const j;
static int const k;

The declarator specifer, static int const is applied to all the identifiers.

You can also extend that logic to functions and function pointers.

static int i, (*fun1)(void), fun2(void);

which is same as:

static int i;
static int (*fun1)(void);
static int fun2(void);

As far as the appears in an expression part goes, there is some commentary at http://c0x.coding-guidelines.com/6.7.5.pdf. It says:

Semantics

Each declarator declares one identifier, and asserts that when an operand of the same form as the declarator appears in an expression, it designates a function or object with the scope, storage duration, and type indicated by the declaration specifiers.

Commentary

The form of an identifier in an expression is likely to be the same as that in the declarator. For instance, the declarator * x will have this form in an expression when the value pointed to by x is required and the declarator y[2] will have this form in an expression when an element of the array y is referred to. It is the declarator portion of a declaration that declares the identifier. There is a special kind of declarator, an abstract-declarator, which does not declare an identifier

I interpret the above to mean:

If you declare:

int *x;

and use *x in an expression, the type of *x is int.

If you declare

static int const *x;

and use *x in an expression, the type of *x is static int const.

Additional references

Static Variable Declaration (C)

Is [ ] also a declarator (when used in parameter declaration) in C?

C -- Accessing a non-const through const declaration

like image 27
R Sahu Avatar answered Nov 03 '22 03:11

R Sahu


Say you have the declaration

int foo[42];

The declarator part is foo[42]. Whenever something of same form (ie foo followed by [ followed by an expression followed by ]) appears within an expression (and the delaration is in scope), the type of that sub-expression will be of the declared type int.

To put it another way: As far as syntax goes, a declaration like

int *bar;

does not declare bar to be of type int *, but instead declares *foo to be of type int.

For a more involved example, take the declaration

float (*op[42])(float, float);

In an expression, an operand of same form could look like this

c = (*op[i])(a, b);

According to the quotation, the right-hand side would have type float.

This implies that

*op[i]

must have function type (we ignore the fact that function designators decay to corresponding pointer types and function invocation via postfix () actually works on pointers, not designators).

This in turn implies that

op[i]

must denote a function pointer and we finally arrive at

op

denoting an array of function pointers as that's what we can apply postfix [] on and get back the correct type.

Fun, isn't it ;)

like image 129
Christoph Avatar answered Nov 03 '22 03:11

Christoph