clanguage-lawyerc11c23

Is { struct-declaration-list } a block?


Is { struct-declaration-list } in C11 (as known as { member-declaration-list } in C23) a block?

The original issue: I cannot find the exact definition of the term "block" in the C standard (C11, C23).

For example: C11 prescribes that:

A compound statement is a block.

and defines the compound statement as:

compound-statement:
    { block-item-listopt }

The { struct-declaration-list } may look similar to { block-item-listopt } (i.e. "something" which is eclosed in between the { and }). However, I cannot find the proof or disproof that { struct-declaration-list } is a block.


GNU C Language Manual says that (emphases added):

A block is a construct that contains multiple statements of any kind. It begins with ‘{’ and ends with ‘}’, and has a series of statements and declarations in between. Another name for blocks is compound statements.

So, it first says "statements" and second says "statements and declarations". Confused.

Wikipedia says that (emphasis added):

In computer programming, a block or code block or block of code is a lexical structure of source code which is grouped together.

and then says:

In C, blocks are delimited by curly braces - "{" and "}".

So, per Wikipedia the { struct-declaration-list } is a block.


Solution

  • A struct-declaration-list or member-declaration-list is not a block.

    C 2011 specifies blocks in clause 6.8, “Statements and blocks.” It says blocks are:

    The above includes the body of a function definition since it is a compound statement.

    C 2024 also specifies blocks in clause 6.8 but specifies most of them in the formal grammar. The natural language text says a block is a primary block, a secondary block, or the block associated with a function definition. The first two refer to the primary-block and secondary-block grammar tokens. The primary-block token includes compound-statement, selection-statement, and iteration-statement. In the grammar for each of those statements, the secondary-block token appears as each of their substatements. The compound-statement of a function definition does not pass through the primary-block token but is a block due to the natural language statement. So the blocks in C 2024 are the same as in C 2011.

    A block is either a primary block, a secondary block, or the block associated with a function definition;…

    None of these is a struct-declaration-list or member-declaration-list. (While the same sequence of some tokens could, in isolation, be either a struct-declaration-list or a compound-statement, a token sequence that passes through the struct-declaration-list or member-declaration-list token, when parsing a full translation unit, does not pass through any of the tokens or statements designated as blocks.) Further, it would be impossible for a struct-declaration-list or member-declaration-list to be a block as then the member names declared in it would be out of scope after the list, making it impossible to refer to members of structures or unions.

    (Note the parameters for a function definition are declared outside the block that is the function body but are associated with the block’s scope by C 2024 6.2.1.)