This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

390
cppdraft/dcl/pre.md Normal file
View File

@@ -0,0 +1,390 @@
[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)