Files
cppdraft_translate/cppdraft/dcl/pre.md
2025-10-25 03:02:53 +03:00

391 lines
29 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[dcl.pre]
# 9 Declarations [[dcl]](./#dcl)
## 9.1 Preamble [dcl.pre]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L11)
Declarations generally specify how names are to be interpreted[.](#1.sentence-1)
Declarations have
the form
[declaration-seq:](#nt:declaration-seq "9.1Preamble[dcl.pre]")
[*declaration*](#nt:declaration "9.1Preamble[dcl.pre]") [*declaration-seq*](#nt:declaration-seq "9.1Preamble[dcl.pre]")opt
[declaration:](#nt:declaration "9.1Preamble[dcl.pre]")
[*name-declaration*](#nt:name-declaration "9.1Preamble[dcl.pre]")
[*special-declaration*](#nt:special-declaration "9.1Preamble[dcl.pre]")
[name-declaration:](#nt:name-declaration "9.1Preamble[dcl.pre]")
[*block-declaration*](#nt:block-declaration "9.1Preamble[dcl.pre]")
[*nodeclspec-function-declaration*](#nt:nodeclspec-function-declaration "9.1Preamble[dcl.pre]")
[*function-definition*](dcl.fct.def.general#nt:function-definition "9.6.1General[dcl.fct.def.general]")
[*friend-type-declaration*](class.mem.general#nt:friend-type-declaration "11.4.1General[class.mem.general]")
[*template-declaration*](temp.pre#nt:template-declaration "13.1Preamble[temp.pre]")
[*deduction-guide*](temp.deduct.guide#nt:deduction-guide "13.7.2.3Deduction guides[temp.deduct.guide]")
[*linkage-specification*](dcl.link#nt:linkage-specification "9.12Linkage specifications[dcl.link]")
[*namespace-definition*](namespace.def.general#nt:namespace-definition "9.9.2.1General[namespace.def.general]")
[*empty-declaration*](#nt:empty-declaration "9.1Preamble[dcl.pre]")
[*attribute-declaration*](#nt:attribute-declaration "9.1Preamble[dcl.pre]")
[*module-import-declaration*](module.import#nt:module-import-declaration "10.3Import declaration[module.import]")
[special-declaration:](#nt:special-declaration "9.1Preamble[dcl.pre]")
[*explicit-instantiation*](temp.explicit#nt:explicit-instantiation "13.9.3Explicit instantiation[temp.explicit]")
[*explicit-specialization*](temp.expl.spec#nt:explicit-specialization "13.9.4Explicit specialization[temp.expl.spec]")
[*export-declaration*](module.interface#nt:export-declaration "10.2Export declaration[module.interface]")
[block-declaration:](#nt:block-declaration "9.1Preamble[dcl.pre]")
[*simple-declaration*](#nt:simple-declaration "9.1Preamble[dcl.pre]")
[*asm-declaration*](dcl.asm#nt:asm-declaration "9.11The asm declaration[dcl.asm]")
[*namespace-alias-definition*](namespace.alias#nt:namespace-alias-definition "9.9.3Namespace alias[namespace.alias]")
[*using-declaration*](namespace.udecl#nt:using-declaration "9.10The using declaration[namespace.udecl]")
[*using-enum-declaration*](enum.udecl#nt:using-enum-declaration "9.8.2The using enum declaration[enum.udecl]")
[*using-directive*](namespace.udir#nt:using-directive "9.9.4Using namespace directive[namespace.udir]")
[*static_assert-declaration*](#nt:static_assert-declaration "9.1Preamble[dcl.pre]")
[*consteval-block-declaration*](#nt:consteval-block-declaration "9.1Preamble[dcl.pre]")
[*alias-declaration*](#nt:alias-declaration "9.1Preamble[dcl.pre]")
[*opaque-enum-declaration*](dcl.enum#nt:opaque-enum-declaration "9.8.1Enumeration declarations[dcl.enum]")
[nodeclspec-function-declaration:](#nt:nodeclspec-function-declaration "9.1Preamble[dcl.pre]")
[*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt [*declarator*](dcl.decl.general#nt:declarator "9.3.1General[dcl.decl.general]") ;
[alias-declaration:](#nt:alias-declaration "9.1Preamble[dcl.pre]")
using [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt = [*defining-type-id*](dcl.name#nt:defining-type-id "9.3.2Type names[dcl.name]") ;
[sb-identifier:](#nt:sb-identifier "9.1Preamble[dcl.pre]")
...opt [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt
[sb-identifier-list:](#nt:sb-identifier-list "9.1Preamble[dcl.pre]")
[*sb-identifier*](#nt:sb-identifier "9.1Preamble[dcl.pre]")
[*sb-identifier-list*](#nt:sb-identifier-list "9.1Preamble[dcl.pre]") , [*sb-identifier*](#nt:sb-identifier "9.1Preamble[dcl.pre]")
[structured-binding-declaration:](#nt:structured-binding-declaration "9.1Preamble[dcl.pre]")
[*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt [*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1General[dcl.spec.general]") [*ref-qualifier*](dcl.decl.general#nt:ref-qualifier "9.3.1General[dcl.decl.general]")opt [ [*sb-identifier-list*](#nt:sb-identifier-list "9.1Preamble[dcl.pre]") ]
[simple-declaration:](#nt:simple-declaration "9.1Preamble[dcl.pre]")
[*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1General[dcl.spec.general]") [*init-declarator-list*](dcl.decl.general#nt:init-declarator-list "9.3.1General[dcl.decl.general]")opt ;
[*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") [*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1General[dcl.spec.general]") [*init-declarator-list*](dcl.decl.general#nt:init-declarator-list "9.3.1General[dcl.decl.general]") ;
[*structured-binding-declaration*](#nt:structured-binding-declaration "9.1Preamble[dcl.pre]") [*initializer*](dcl.init.general#nt:initializer "9.5.1General[dcl.init.general]") ;
[static_assert-message:](#nt:static_assert-message "9.1Preamble[dcl.pre]")
[*unevaluated-string*](lex.string.uneval#nt:unevaluated-string "5.13.6Unevaluated strings[lex.string.uneval]")
[*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]")
[static_assert-declaration:](#nt:static_assert-declaration "9.1Preamble[dcl.pre]")
static_assert ( [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") ) ;
static_assert ( [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") , [*static_assert-message*](#nt:static_assert-message "9.1Preamble[dcl.pre]") ) ;
[consteval-block-declaration:](#nt:consteval-block-declaration "9.1Preamble[dcl.pre]")
consteval [*compound-statement*](stmt.block#nt:compound-statement "8.4Compound statement or block[stmt.block]")
[empty-declaration:](#nt:empty-declaration "9.1Preamble[dcl.pre]")
;
[attribute-declaration:](#nt:attribute-declaration "9.1Preamble[dcl.pre]")
[*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") ;
[*Note [1](#note-1)*:
[*asm-declaration*](dcl.asm#nt:asm-declaration "9.11The asm declaration[dcl.asm]")*s* are described in [[dcl.asm]](dcl.asm "9.11The asm declaration"), and[*linkage-specification*](dcl.link#nt:linkage-specification "9.12Linkage specifications[dcl.link]")*s* are described in [[dcl.link]](dcl.link "9.12Linkage specifications");[*function-definition*](dcl.fct.def.general#nt:function-definition "9.6.1General[dcl.fct.def.general]")*s* are described in [[dcl.fct.def]](dcl.fct.def "9.6Function definitions") and[*template-declaration*](temp.pre#nt:template-declaration "13.1Preamble[temp.pre]")*s* and[*deduction-guide*](temp.deduct.guide#nt:deduction-guide "13.7.2.3Deduction guides[temp.deduct.guide]")*s* are described in [[temp.deduct.guide]](temp.deduct.guide "13.7.2.3Deduction guides");[*namespace-definition*](namespace.def.general#nt:namespace-definition "9.9.2.1General[namespace.def.general]")*s* are described in [[namespace.def]](namespace.def "9.9.2Namespace definition"),[*using-declaration*](namespace.udecl#nt:using-declaration "9.10The using declaration[namespace.udecl]")*s* are described in [[namespace.udecl]](namespace.udecl "9.10The using declaration") and[*using-directive*](namespace.udir#nt:using-directive "9.9.4Using namespace directive[namespace.udir]")*s* are described in [[namespace.udir]](namespace.udir "9.9.4Using namespace directive")[.](#1.sentence-3)
— *end note*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L132)
Certain declarations contain one or more scopes ([[basic.scope.scope]](basic.scope.scope "6.4.1General"))[.](#2.sentence-1)
Unless otherwise stated, utterances in[[dcl]](dcl "9Declarations") about components in, of, or contained by a
declaration or subcomponent thereof refer only to those components of
the declaration that are not nested within scopes nested within
the declaration[.](#2.sentence-2)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L142)
If a [*name-declaration*](#nt:name-declaration "9.1Preamble[dcl.pre]") matches
the syntactic requirements of [*friend-type-declaration*](class.mem.general#nt:friend-type-declaration "11.4.1General[class.mem.general]"),
it is a [*friend-type-declaration*](class.mem.general#nt:friend-type-declaration "11.4.1General[class.mem.general]")[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L147)
A[*simple-declaration*](#nt:simple-declaration "9.1Preamble[dcl.pre]") or[*nodeclspec-function-declaration*](#nt:nodeclspec-function-declaration "9.1Preamble[dcl.pre]") of the form
[*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt [*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1General[dcl.spec.general]")opt [*init-declarator-list*](dcl.decl.general#nt:init-declarator-list "9.3.1General[dcl.decl.general]")opt ;
is divided into three parts[.](#4.sentence-1)
Attributes are described in [[dcl.attr]](dcl.attr "9.13Attributes")[.](#4.sentence-2)
[*decl-specifier*](dcl.spec.general#nt:decl-specifier "9.2.1General[dcl.spec.general]")*s*, the principal components of
a [*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1General[dcl.spec.general]"), are described in [[dcl.spec]](dcl.spec "9.2Specifiers")[.](#4.sentence-3)
[*declarator*](dcl.decl.general#nt:declarator "9.3.1General[dcl.decl.general]")*s*, the components of an[*init-declarator-list*](dcl.decl.general#nt:init-declarator-list "9.3.1General[dcl.decl.general]"), are described in [[dcl.decl]](dcl.decl "9.3Declarators")[.](#4.sentence-4)
The [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") appertains to each of the entities declared by
the [*declarator*](dcl.decl.general#nt:declarator "9.3.1General[dcl.decl.general]")*s* of the [*init-declarator-list*](dcl.decl.general#nt:init-declarator-list "9.3.1General[dcl.decl.general]")[.](#4.sentence-5)
[*Note [2](#note-2)*:
In the declaration for an entity, attributes appertaining to that
entity can appear at the start of the declaration and after the[*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") for that declaration[.](#4.sentence-6)
— *end note*]
[*Example [1](#example-1)*: [[noreturn]] void f [[noreturn]] (); // OK — *end example*]
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L175)
If a [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") is a name, the[*init-declarator*](dcl.decl.general#nt:init-declarator "9.3.1General[dcl.decl.general]") and (hence) the declaration introduce that name[.](#5.sentence-1)
[*Note [3](#note-3)*:
Otherwise, the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") is
a [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified names[expr.prim.id.qual]") or
names a destructor or
its [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2Unqualified names[expr.prim.id.unqual]") is a [*template-id*](temp.names#nt:template-id "13.3Names of template specializations[temp.names]") and
no name is introduced[.](#5.sentence-2)
— *end note*]
The [*defining-type-specifier*](dcl.type.general#nt:defining-type-specifier "9.2.9.1General[dcl.type.general]")*s* ([[dcl.type]](dcl.type "9.2.9Type specifiers")) in
the [*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1General[dcl.spec.general]") and
the recursive [*declarator*](dcl.decl.general#nt:declarator "9.3.1General[dcl.decl.general]") structure
describe a type ([[dcl.meaning]](dcl.meaning "9.3.4Meaning of declarators")),
which is then associated with the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]")[.](#5.sentence-3)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L191)
In a [*simple-declaration*](#nt:simple-declaration "9.1Preamble[dcl.pre]"), the optional[*init-declarator-list*](dcl.decl.general#nt:init-declarator-list "9.3.1General[dcl.decl.general]") can be omitted only when declaring a
class ([[class.pre]](class.pre "11.1Preamble")) or enumeration ([[dcl.enum]](dcl.enum "9.8.1Enumeration declarations")), that is,
when the [*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1General[dcl.spec.general]") contains either a[*class-specifier*](class.pre#nt:class-specifier "11.1Preamble[class.pre]"), an [*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5Elaborated type specifiers[dcl.type.elab]") with
a [*class-key*](class.pre#nt:class-key "11.1Preamble[class.pre]") ([[class.name]](class.name "11.3Class names")), or an[*enum-specifier*](dcl.enum#nt:enum-specifier "9.8.1Enumeration declarations[dcl.enum]")[.](#6.sentence-1)
In these cases and whenever a[*class-specifier*](class.pre#nt:class-specifier "11.1Preamble[class.pre]") or [*enum-specifier*](dcl.enum#nt:enum-specifier "9.8.1Enumeration declarations[dcl.enum]") is present in
the [*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1General[dcl.spec.general]"), the identifiers in these specifiers
are also declared (as[*class-name*](class.pre#nt:class-name "11.1Preamble[class.pre]")*s*, [*enum-name*](dcl.enum#nt:enum-name "9.8.1Enumeration declarations[dcl.enum]")*s*, or[*enumerator*](dcl.enum#nt:enumerator "9.8.1Enumeration declarations[dcl.enum]")*s*, depending on the syntax)[.](#6.sentence-2)
In such cases,
the [*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1General[dcl.spec.general]") shall (re)introduce one or more names into
the program[.](#6.sentence-3)
[*Example [2](#example-2)*: enum { }; // errortypedef class { }; // error — *end example*]
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L215)
A [*simple-declaration*](#nt:simple-declaration "9.1Preamble[dcl.pre]") or a [*condition*](stmt.pre#nt:condition "8.1Preamble[stmt.pre]") with a [*structured-binding-declaration*](#nt:structured-binding-declaration "9.1Preamble[dcl.pre]") is called
a [*structured binding declaration*](#def:structured_binding_declaration "9.1Preamble[dcl.pre]") ([[dcl.struct.bind]](dcl.struct.bind "9.7Structured binding declarations"))[.](#7.sentence-1)
Each [*decl-specifier*](dcl.spec.general#nt:decl-specifier "9.2.1General[dcl.spec.general]") in the [*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1General[dcl.spec.general]") shall beconstexpr,constinit,static,thread_local,auto ([[dcl.spec.auto]](dcl.spec.auto "9.2.9.7Placeholder type specifiers")), or
a [*cv-qualifier*](dcl.decl.general#nt:cv-qualifier "9.3.1General[dcl.decl.general]")[.](#7.sentence-2)
The declaration shall contain at most one [*sb-identifier*](#nt:sb-identifier "9.1Preamble[dcl.pre]") whose [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") is preceded by an ellipsis[.](#7.sentence-3)
If the declaration contains any such [*sb-identifier*](#nt:sb-identifier "9.1Preamble[dcl.pre]"),
it shall declare a templated entity ([[temp.pre]](temp.pre "13.1Preamble"))[.](#7.sentence-4)
[*Example [3](#example-3)*: template<class T> concept C = true;
C auto [x, y] = std::pair{1, 2}; // error: constrained [*placeholder-type-specifier*](dcl.spec.auto.general#nt:placeholder-type-specifier "9.2.9.7.1General[dcl.spec.auto.general]")// not permitted for structured bindings — *end example*]
The [*initializer*](dcl.init.general#nt:initializer "9.5.1General[dcl.init.general]") shall be
of the form “= [*assignment-expression*](expr.assign#nt:assignment-expression "7.6.19Assignment and compound assignment operators[expr.assign]")”,
of the form “{ [*assignment-expression*](expr.assign#nt:assignment-expression "7.6.19Assignment and compound assignment operators[expr.assign]") }”,
or
of the form “( [*assignment-expression*](expr.assign#nt:assignment-expression "7.6.19Assignment and compound assignment operators[expr.assign]") )”[.](#7.sentence-5)
If the [*structured-binding-declaration*](#nt:structured-binding-declaration "9.1Preamble[dcl.pre]") appears as
a [*condition*](stmt.pre#nt:condition "8.1Preamble[stmt.pre]"),
the [*assignment-expression*](expr.assign#nt:assignment-expression "7.6.19Assignment and compound assignment operators[expr.assign]") shall be of non-union class type[.](#7.sentence-6)
Otherwise,
the [*assignment-expression*](expr.assign#nt:assignment-expression "7.6.19Assignment and compound assignment operators[expr.assign]") shall be of
array or non-union class type[.](#7.sentence-7)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L250)
If the [*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1General[dcl.spec.general]") contains the typedef specifier, the declaration is a [*typedef declaration*](#def:declaration,typedef "9.1Preamble[dcl.pre]") and each [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") is declared to be a [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4The typedef specifier[dcl.typedef]") ([[dcl.typedef]](dcl.typedef "9.2.4The typedef specifier"))[.](#8.sentence-1)
[*Note [4](#note-4)*:
Such a [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") is
an [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") ([[class.conv.fct]](class.conv.fct "11.4.8.3Conversion functions"))[.](#8.sentence-2)
— *end note*]
Otherwise, if the type associated with a [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") is a function type ([[dcl.fct]](dcl.fct "9.3.4.6Functions")),
the declaration is a [*function declaration*](#def:declaration,function "9.1Preamble[dcl.pre]")[.](#8.sentence-3)
Otherwise, if the type associated with a [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") is an object or reference type, the declaration is
an [*object declaration*](#def:declaration,object "9.1Preamble[dcl.pre]")[.](#8.sentence-4)
Otherwise, the program is ill-formed[.](#8.sentence-5)
[*Example [4](#example-4)*: int f(), x; // OK, function declaration for f and object declaration for xextern void g(), // OK, function declaration for g y; // error: void is not an object type — *end example*]
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L274)
An object definition causes
storage of appropriate size and alignment to be reserved and
any appropriate initialization ([[dcl.init]](dcl.init "9.5Initializers")) to be done[.](#9.sentence-1)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L280)
Syntactic components beyond those found in the general form of[*simple-declaration*](#nt:simple-declaration "9.1Preamble[dcl.pre]") are added to a function declaration to make a[*function-definition*](dcl.fct.def.general#nt:function-definition "9.6.1General[dcl.fct.def.general]")[.](#10.sentence-1)
A token sequence starting with { or = is treated as a [*function-body*](dcl.fct.def.general#nt:function-body "9.6.1General[dcl.fct.def.general]") ([[dcl.fct.def.general]](dcl.fct.def.general "9.6.1General"))
if the type of the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") ([[dcl.meaning.general]](dcl.meaning.general "9.3.4.1General"))
is a function type, and
is otherwise
treated as a [*brace-or-equal-initializer*](dcl.init.general#nt:brace-or-equal-initializer "9.5.1General[dcl.init.general]") ([[dcl.init.general]](dcl.init.general "9.5.1General"))[.](#10.sentence-2)
[*Note [5](#note-5)*:
If the declaration acquires a function type through template instantiation,
the program is ill-formed; see [[temp.spec.general]](temp.spec.general "13.9.1General")[.](#10.sentence-3)
The function type of a function definition
cannot be specified with a [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4The typedef specifier[dcl.typedef]") ([[dcl.fct]](dcl.fct "9.3.4.6Functions"))[.](#10.sentence-4)
— *end note*]
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L298)
A [*nodeclspec-function-declaration*](#nt:nodeclspec-function-declaration "9.1Preamble[dcl.pre]") shall declare a
constructor, destructor, or conversion function[.](#11.sentence-1)
[*Note [6](#note-6)*:
Because a member function cannot be subject to a non-defining declaration
outside of a class definition ([[class.mfct]](class.mfct "11.4.2Member functions")), a [*nodeclspec-function-declaration*](#nt:nodeclspec-function-declaration "9.1Preamble[dcl.pre]") can only be used in a [*template-declaration*](temp.pre#nt:template-declaration "13.1Preamble[temp.pre]") ([[temp.pre]](temp.pre "13.1Preamble")),[*explicit-instantiation*](temp.explicit#nt:explicit-instantiation "13.9.3Explicit instantiation[temp.explicit]") ([[temp.explicit]](temp.explicit "13.9.3Explicit instantiation")), or[*explicit-specialization*](temp.expl.spec#nt:explicit-specialization "13.9.4Explicit specialization[temp.expl.spec]") ([[temp.expl.spec]](temp.expl.spec "13.9.4Explicit specialization"))[.](#11.sentence-2)
— *end note*]
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L309)
If a [*static_assert-message*](#nt:static_assert-message "9.1Preamble[dcl.pre]") matches the syntactic requirements of [*unevaluated-string*](lex.string.uneval#nt:unevaluated-string "5.13.6Unevaluated strings[lex.string.uneval]"),
it is an [*unevaluated-string*](lex.string.uneval#nt:unevaluated-string "5.13.6Unevaluated strings[lex.string.uneval]") and
the text of the [*static_assert-message*](#nt:static_assert-message "9.1Preamble[dcl.pre]") is
the text of the [*unevaluated-string*](lex.string.uneval#nt:unevaluated-string "5.13.6Unevaluated strings[lex.string.uneval]")[.](#12.sentence-1)
Otherwise, a [*static_assert-message*](#nt:static_assert-message "9.1Preamble[dcl.pre]") shall be an expression M such that
- [(12.1)](#12.1)
the expression M.size() is
implicitly convertible to the type std::size_t, and
- [(12.2)](#12.2)
the expression M.data() is
implicitly convertible to the type “pointer to const char”[.](#12.sentence-2)
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L326)
In a [*static_assert-declaration*](#nt:static_assert-declaration "9.1Preamble[dcl.pre]"),
the [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") E is contextually converted to bool and
the converted expression shall be a constant expression ([[expr.const]](expr.const "7.7Constant expressions"))[.](#13.sentence-1)
If the value of the expression E when so converted is true or
the expression is evaluated in the context of a template definition,
the declaration has no effect and
the [*static_assert-message*](#nt:static_assert-message "9.1Preamble[dcl.pre]") is
an unevaluated operand ([[expr.context]](expr.context#term.unevaluated.operand "7.2.3Context dependence"))[.](#13.sentence-2)
Otherwise,
the [*static_assert-declaration*](#nt:static_assert-declaration "9.1Preamble[dcl.pre]") [*fails*](#def:static_assert,failed "9.1Preamble[dcl.pre]") and
- [(13.1)](#13.1)
the program is ill-formed, and
- [(13.2)](#13.2)
if the [*static_assert-message*](#nt:static_assert-message "9.1Preamble[dcl.pre]") is
a [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") M,
* [(13.2.1)](#13.2.1)
M.size() shall be a converted constant expression of
type std::size_t and
let N denote the value of that expression,
* [(13.2.2)](#13.2.2)
M.data(), implicitly converted to
the type “pointer to const char”,
shall be a core constant expression and let D denote the converted expression,
* [(13.2.3)](#13.2.3)
for each i where 0≤i<N,D[i] shall be an integral constant expression, and
* [(13.2.4)](#13.2.4)
the text of the [*static_assert-message*](#nt:static_assert-message "9.1Preamble[dcl.pre]") is formed by
the sequence of N code units, starting at D, of
the ordinary literal encoding ([[lex.charset]](lex.charset "5.3.1Character sets"))[.](#13.sentence-3)
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L364)
*Recommended practice*: When a [*static_assert-declaration*](#nt:static_assert-declaration "9.1Preamble[dcl.pre]") fails,
the resulting diagnostic message should include the text of
the [*static_assert-message*](#nt:static_assert-message "9.1Preamble[dcl.pre]"), if one is supplied[.](#14.sentence-1)
[*Example [5](#example-5)*: static_assert(sizeof(int) == sizeof(void*), "wrong pointer size");static_assert(sizeof(int[2])); // OK, narrowing allowedtemplate <class T>void f(T t) {if constexpr (sizeof(T) == sizeof(int)) { use(t); } else {static_assert(false, "must be int-sized"); }}void g(char c) { f(0); // OK f(c); // error on implementations where sizeof(int) > 1: must be int-sized} — *end example*]
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L390)
For a [*consteval-block-declaration*](#nt:consteval-block-declaration "9.1Preamble[dcl.pre]") D,
the expression E corresponding to D is: [] -> void static consteval [*compound-statement*](stmt.block#nt:compound-statement "8.4Compound statement or block[stmt.block]") ()E shall be a constant expression ([[expr.const]](expr.const "7.7Constant expressions"))[.](#15.sentence-1)
[*Note [7](#note-7)*:
The evaluation of the expression
corresponding to a [*consteval-block-declaration*](#nt:consteval-block-declaration "9.1Preamble[dcl.pre]") ([[lex.phases]](lex.phases "5.2Phases of translation"))
can produce injected declarations as side effects[.](#15.sentence-2)
— *end note*]
[*Example [6](#example-6)*: struct S;consteval { std::meta::define_aggregate(^^S, {}); // OKtemplate<class T>struct X { }; // error: local templates are not allowedtemplate<class T>concept C = true; // error: local concepts are not allowedreturn; // OK} — *end example*]
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L419)
An [*empty-declaration*](#nt:empty-declaration "9.1Preamble[dcl.pre]") has no effect[.](#16.sentence-1)
[17](#17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L422)
Except where otherwise specified, the meaning of an [*attribute-declaration*](#nt:attribute-declaration "9.1Preamble[dcl.pre]") is implementation-defined[.](#17.sentence-1)