2023-01-26
org: | ISO/IEC JCT1/SC22/WG14 | document: | N3090 | |
target: | IS 9899:2023 | version: | 2 | |
date: | 2023-01-26 | license: | CC BY |
N3080 original version
N3090 better capture compound literals in function prototype scope
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 (mainly NB comments 066 and 067, perhaps marginally also 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.
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 specifiersSC
(possibly empty)110), type nameT
, 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,
typeof(T) ID = { IL }; SC
where
ID
is an identifier that is unique for the whole program text and whereIL
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. If the compound literal is associated with function prototype scope, constraints as if in block scope apply.
Semantics
5
AFor a compound literal associated with function prototype scope, the type is determined as if in block scope and no object is created; if it is a compound literal constant it is evaluated at translation time; if it is not a compound literal constant, neither the compound literal as a whole nor any of the initializers are evaluated. 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 specifierscontain other specifiers thanare absent or containconstexpr
,static
,register
, orthread_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 specifierconstexpr
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 (as if) evaluated once prior to program startup.
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 withconstexpr
, need not designate distinct objects.113)