handle NB comments concerning compound literals

Jens Gustedt (INRIA France)

2023-01-08

org: ISO/IEC JCT1/SC22/WG14 document: N3080
target: IS 9899:2023 version: 1
date: 2023-01-08 license: CC BY

Problem description

Several NB comments raised questions about the amended definition of compound literals, and in particular of the possible placement of compound literals with storage-class specifiers (see NB comments 066, 067, 080, and 083). It seems that the proposed text so far does not properly distinguish the properties that are deduced from the lexical placement of compound literals from their execution behavior.

The proposed text tries to clarify this situation. It moves the definition of the lexical scope to which compound literals associate to 6.2.1, which is the context of the existing provisions for lexical scope (so far only defined for identifiers and type names).

With that definition of scope in place it complements the definition with a definition for compound literals in function prototype scope (completely missing in all previous versions of the standard) and with a hopefully better explicit definition of certain properties of compound literals in file scope or block scope. In particular it insists at which points in time of the execution initializers are evaluated: for constexpr at translation time, for static and storage duration before program execution, and for automatic storage duration whenever the compound literal is evaluated.

Proposed resolution

6.2.1 Scopes of identifiers, type names, and compound literals

8 As a special case, a type name (which is not a declaration of an identifier) is considered to have a scope that begins just after the place within the type name where the omitted identifier would appear were it not omitted. A compound literal (which is an expression that provides access to an anonymous object) is associated with the enclosing scope that corresponds to the placement of the compound literal in the program; that scope is either file scope, function prototype scope, or block scope.

Forward references: declarations (6.7), function calls (6.5.2.2), compound literals (6.5.2.5), function definitions (6.9.1), identifiers (6.4.2), macro replacement (6.10.4), name spaces of identifiers (6.2.3), source file inclusion (6.10.2), statements and blocks (6.8).

6.5.2.5 Compound literals

4 If the compound literal is evaluated outside the body of a function and outside of any parameter list, it is associated with file scope; otherwise, it is associated with the enclosing block. Depending on this association, If the compound literal is associated with file scope or block scope (see 6.2.1), the storage-class specifiers SC (possibly empty)110), type name T, and initializer list, if any, shall be such that they are valid specifiers for an object definition in file scope or block scope, respectively, of the following form,

SC typeof(T) ID = { IL };

where ID is an identifier that is unique for the whole program text and where IL is a (possibly empty) initializer list with nested structure, designators, values and types as the initializer list of the compound literal. All the constraints for storage class specifiers in 6.7.1 also apply correspondingly to compound literals.

Semantics

5 A For a compound literal with function prototype scope, the type of the compound literal is the complete type as given by the type name (possibly completed by the initializer to a complete array type), it is not evaluated, possible storage-class specifiers are ignored and no object is created. Otherwise, a compound literal provides access to an unnamed object whose value, type, storage duration, initializer, and other properties are as if given by the definition syntax in the constraints; if the storage duration is automatic, the lifetime of the instance of the unnamed object is the current execution of the enclosing block111) If the storage-class specifiers contain other specifiers than are absent or contain constexpr, static, register, or thread_local the behavior is as if the object were declared and initialized in the corresponding scope with these storage-class specifiers; if another storage-class specifier is present, the behavior is undefined. If the storage-class specifier constexpr is present, the initializer is evaluated at translation time. Otherwise, if the storage duration is automatic, the initializer is evaluated at each evaluation of the compound literal; if the storage duration is static or thread the initializer is evaluated once prior to program execution.

6 The value of the compound literal is that of an lvalue corresponding to the unnamed object.

7 All the semantic rules for initializer lists in 6.7.10 also apply to compound literals.112)

8 String literals, and compound literals with const-qualified types, including those specified with constexpr, need not designate distinct objects.113)

Poll

  1. Does WG14 agree to integrate the changes of N3080 for the definition of compound literals?