215 lines
10 KiB
Markdown
215 lines
10 KiB
Markdown
[basic.def]
|
||
|
||
# 6 Basics [[basic]](./#basic)
|
||
|
||
## 6.2 Declarations and definitions [basic.def]
|
||
|
||
[1](#1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L166)
|
||
|
||
A declaration ([[basic.pre]](basic.pre "6.1 Preamble")) may (re)introduce
|
||
one or more names and/or entities into a translation
|
||
unit[.](#1.sentence-1)
|
||
|
||
If so, the
|
||
declaration specifies the interpretation and semantic properties of these names[.](#1.sentence-2)
|
||
|
||
A declaration of an entity X is
|
||
a redeclaration of X if another declaration of X is reachable from it ([[module.reach]](module.reach "10.7 Reachability"));
|
||
otherwise, it is a [*first declaration*](#def:declaration,first "6.2 Declarations and definitions [basic.def]")[.](#1.sentence-3)
|
||
|
||
A declaration may also have effects including:
|
||
|
||
- [(1.1)](#1.1)
|
||
|
||
a static assertion ([[dcl.pre]](dcl.pre "9.1 Preamble")),
|
||
|
||
- [(1.2)](#1.2)
|
||
|
||
controlling template instantiation ([[temp.explicit]](temp.explicit "13.9.3 Explicit instantiation")),
|
||
|
||
- [(1.3)](#1.3)
|
||
|
||
guiding template argument deduction for constructors ([[temp.deduct.guide]](temp.deduct.guide "13.7.2.3 Deduction guides")),
|
||
|
||
- [(1.4)](#1.4)
|
||
|
||
use of [attributes](dcl.attr "9.13 Attributes [dcl.attr]"), and
|
||
|
||
- [(1.5)](#1.5)
|
||
|
||
nothing (in the case of an [*empty-declaration*](dcl.pre#nt:empty-declaration "9.1 Preamble [dcl.pre]"))[.](#1.sentence-4)
|
||
|
||
[2](#2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L188)
|
||
|
||
Each entity declared by a [*declaration*](dcl.pre#nt:declaration "9.1 Preamble [dcl.pre]") is
|
||
also [*defined*](#def:define "6.2 Declarations and definitions [basic.def]") by that declaration unless:
|
||
|
||
- [(2.1)](#2.1)
|
||
|
||
it declares a function
|
||
without specifying the function's body ([[dcl.fct.def]](dcl.fct.def "9.6 Function definitions")),
|
||
|
||
- [(2.2)](#2.2)
|
||
|
||
it contains
|
||
theextern specifier ([[dcl.stc]](dcl.stc "9.2.2 Storage class specifiers")) or a[*linkage-specification*](dcl.link#nt:linkage-specification "9.12 Linkage specifications [dcl.link]")[15](#footnote-15 "Appearing inside the brace-enclosed declaration-seq in a linkage-specification does not affect whether a declaration is a definition.") ([[dcl.link]](dcl.link "9.12 Linkage specifications"))
|
||
and neither an [*initializer*](dcl.init.general#nt:initializer "9.5.1 General [dcl.init.general]") nor a[*function-body*](dcl.fct.def.general#nt:function-body "9.6.1 General [dcl.fct.def.general]"),
|
||
|
||
- [(2.3)](#2.3)
|
||
|
||
it declares a non-inline static data member in a class
|
||
definition ([[class.mem]](class.mem "11.4 Class members"), [[class.static]](class.static "11.4.9 Static members")),
|
||
|
||
- [(2.4)](#2.4)
|
||
|
||
it declares a static data member outside a class definition
|
||
and the variable was defined within the class with the constexpr specifier ([[class.static.data]](class.static.data "11.4.9.3 Static data members")) (this usage is deprecated; see [[depr.static.constexpr]](depr.static.constexpr "D.7 Redeclaration of static constexpr data members")),
|
||
|
||
- [(2.5)](#2.5)
|
||
|
||
it is an [*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]") ([[class.name]](class.name "11.3 Class names")),
|
||
|
||
- [(2.6)](#2.6)
|
||
|
||
it is an[*opaque-enum-declaration*](dcl.enum#nt:opaque-enum-declaration "9.8.1 Enumeration declarations [dcl.enum]") ([[dcl.enum]](dcl.enum "9.8.1 Enumeration declarations")),
|
||
|
||
- [(2.7)](#2.7)
|
||
|
||
it is a[*template-parameter*](temp.param#nt:template-parameter "13.2 Template parameters [temp.param]") ([[temp.param]](temp.param "13.2 Template parameters")),
|
||
|
||
- [(2.8)](#2.8)
|
||
|
||
it is a[*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") ([[dcl.fct]](dcl.fct "9.3.4.6 Functions")) in a functiondeclarator that is not the [*declarator*](dcl.decl.general#nt:declarator "9.3.1 General [dcl.decl.general]") of a[*function-definition*](dcl.fct.def.general#nt:function-definition "9.6.1 General [dcl.fct.def.general]"),
|
||
|
||
- [(2.9)](#2.9)
|
||
|
||
it is atypedef declaration ([[dcl.typedef]](dcl.typedef "9.2.4 The typedef specifier")),
|
||
|
||
- [(2.10)](#2.10)
|
||
|
||
it is
|
||
an [*alias-declaration*](dcl.pre#nt:alias-declaration "9.1 Preamble [dcl.pre]") ([[dcl.typedef]](dcl.typedef "9.2.4 The typedef specifier")),
|
||
|
||
- [(2.11)](#2.11)
|
||
|
||
it is
|
||
a [*namespace-alias-definition*](namespace.alias#nt:namespace-alias-definition "9.9.3 Namespace alias [namespace.alias]") ([[namespace.alias]](namespace.alias "9.9.3 Namespace alias")),
|
||
|
||
- [(2.12)](#2.12)
|
||
|
||
it is
|
||
a [*using-declaration*](namespace.udecl#nt:using-declaration "9.10 The using declaration [namespace.udecl]") ([[namespace.udecl]](namespace.udecl "9.10 The using declaration")),
|
||
|
||
- [(2.13)](#2.13)
|
||
|
||
it is
|
||
a [*deduction-guide*](temp.deduct.guide#nt:deduction-guide "13.7.2.3 Deduction guides [temp.deduct.guide]") ([[temp.deduct.guide]](temp.deduct.guide "13.7.2.3 Deduction guides")),
|
||
|
||
- [(2.14)](#2.14)
|
||
|
||
it is
|
||
a [*static_assert-declaration*](dcl.pre#nt:static_assert-declaration "9.1 Preamble [dcl.pre]") ([[dcl.pre]](dcl.pre "9.1 Preamble")),
|
||
|
||
- [(2.15)](#2.15)
|
||
|
||
it is
|
||
a [*consteval-block-declaration*](dcl.pre#nt:consteval-block-declaration "9.1 Preamble [dcl.pre]"),
|
||
|
||
- [(2.16)](#2.16)
|
||
|
||
it is an[*attribute-declaration*](dcl.pre#nt:attribute-declaration "9.1 Preamble [dcl.pre]") ([[dcl.pre]](dcl.pre "9.1 Preamble")),
|
||
|
||
- [(2.17)](#2.17)
|
||
|
||
it is an[*empty-declaration*](dcl.pre#nt:empty-declaration "9.1 Preamble [dcl.pre]") ([[dcl.pre]](dcl.pre "9.1 Preamble")),
|
||
|
||
- [(2.18)](#2.18)
|
||
|
||
it is
|
||
a [*using-directive*](namespace.udir#nt:using-directive "9.9.4 Using namespace directive [namespace.udir]") ([[namespace.udir]](namespace.udir "9.9.4 Using namespace directive")),
|
||
|
||
- [(2.19)](#2.19)
|
||
|
||
it is
|
||
a [*using-enum-declaration*](enum.udecl#nt:using-enum-declaration "9.8.2 The using enum declaration [enum.udecl]") ([[enum.udecl]](enum.udecl "9.8.2 The using enum declaration")),
|
||
|
||
- [(2.20)](#2.20)
|
||
|
||
it is
|
||
a [*template-declaration*](temp.pre#nt:template-declaration "13.1 Preamble [temp.pre]") ([[temp.pre]](temp.pre "13.1 Preamble"))
|
||
whose [*template-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]") is not followed by
|
||
either a [*concept-definition*](temp.concept#nt:concept-definition "13.7.9 Concept definitions [temp.concept]") or a [*declaration*](dcl.pre#nt:declaration "9.1 Preamble [dcl.pre]") that defines a function, a class, a variable, or a static data member,
|
||
|
||
- [(2.21)](#2.21)
|
||
|
||
it is
|
||
an explicit instantiation declaration ([[temp.explicit]](temp.explicit "13.9.3 Explicit instantiation")), or
|
||
|
||
- [(2.22)](#2.22)
|
||
|
||
it is
|
||
an [explicit specialization](temp.expl.spec "13.9.4 Explicit specialization [temp.expl.spec]") whose[*declaration*](dcl.pre#nt:declaration "9.1 Preamble [dcl.pre]") is not a definition[.](#2.sentence-1)
|
||
|
||
A declaration is said to be a [*definition*](#def:definition "6.2 Declarations and definitions [basic.def]") of each entity that it defines[.](#2.sentence-2)
|
||
|
||
[*Example [1](#example-1)*:
|
||
|
||
All but one of the following are definitions:int a; // defines aextern const int c = 1; // defines cint f(int x) { return x+a; } // defines f and defines xstruct S { int a; int b; }; // defines S, S::a, and S::bstruct X { // defines Xint x; // defines non-static data member xstatic int y; // declares static data member y X(): x(0) { } // defines a constructor of X};int X::y = 1; // defines X::yenum { up, down }; // defines up and downnamespace N { int d; } // defines N and N::d X anX; // defines anX whereas these are just declarations:extern int a; // declares aextern const int c; // declares cint f(int); // declares fstruct S; // declares Stypedef int Int; // declares Intnamespace N1 = N; // declares N1extern X anotherX; // declares anotherXusing N::d; // declares d
|
||
|
||
â *end example*]
|
||
|
||
[3](#3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L304)
|
||
|
||
[*Note [1](#note-1)*:
|
||
|
||
In some circumstances, C++ implementations implicitly define the
|
||
default constructor ([[class.default.ctor]](class.default.ctor "11.4.5.2 Default constructors")),
|
||
copy constructor, move constructor ([[class.copy.ctor]](class.copy.ctor "11.4.5.3 Copy/move constructors")),
|
||
copy assignment operator, move assignment operator ([[class.copy.assign]](class.copy.assign "11.4.6 Copy/move assignment operator")),
|
||
or [destructor](class.dtor "11.4.7 Destructors [class.dtor]") member functions[.](#3.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[*Example [2](#example-2)*:
|
||
|
||
Given#include <string>struct C { std::string s; // std::string is the standard library class ([[string.classes]](string.classes "27.4 String classes"))};
|
||
|
||
int main() { C a;
|
||
C b = a;
|
||
b = a;} the implementation will implicitly define functions to make the
|
||
definition of C equivalent tostruct C { std::string s;
|
||
C() : s() { } C(const C& x): s(x.s) { } C(C&& x): s(static_cast<std::string&&>(x.s)) { }*//* : s(std::move(x.s)) { } C& operator=(const C& x) { s = x.s; return *this; } C& operator=(C&& x) { s = static_cast<std::string&&>(x.s); return *this; }*//* { s = std::move(x.s); return *this; }~C() { }};
|
||
|
||
â *end example*]
|
||
|
||
[4](#4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L345)
|
||
|
||
[*Note [2](#note-2)*:
|
||
|
||
A class name can also be implicitly declared by an[*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]") ([[dcl.type.elab]](dcl.type.elab "9.2.9.5 Elaborated type specifiers"))[.](#4.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[5](#5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L351)
|
||
|
||
In the definition of an object,
|
||
the type of that object shall not be
|
||
an incomplete type ([[basic.types.general]](basic.types.general#term.incomplete.type "6.9.1 General")),
|
||
an abstract class type ([[class.abstract]](class.abstract "11.7.4 Abstract classes")), or
|
||
a (possibly multidimensional) array thereof[.](#5.sentence-1)
|
||
|
||
[15)](#footnote-15)[15)](#footnoteref-15)
|
||
|
||
Appearing inside the brace-enclosed[*declaration-seq*](dcl.pre#nt:declaration-seq "9.1 Preamble [dcl.pre]") in a [*linkage-specification*](dcl.link#nt:linkage-specification "9.12 Linkage specifications [dcl.link]") does
|
||
not affect whether a declaration is a definition[.](#footnote-15.sentence-1)
|