Init
This commit is contained in:
377
cppdraft/expr/call.md
Normal file
377
cppdraft/expr/call.md
Normal file
@@ -0,0 +1,377 @@
|
||||
[expr.call]
|
||||
|
||||
# 7 Expressions [[expr]](./#expr)
|
||||
|
||||
## 7.6 Compound expressions [[expr.compound]](expr.compound#expr.call)
|
||||
|
||||
### 7.6.1 Postfix expressions [[expr.post]](expr.post#expr.call)
|
||||
|
||||
#### 7.6.1.3 Function call [expr.call]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3749)
|
||||
|
||||
A function call is a postfix expression followed by parentheses
|
||||
containing a possibly empty, comma-separated list of[*initializer-clause*](dcl.init.general#nt:initializer-clause "9.5.1 General [dcl.init.general]")*s* which
|
||||
constitute the arguments to the function[.](#1.sentence-1)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
If the postfix expression is a function or member function name,
|
||||
the appropriate function and the validity of the call
|
||||
are determined according to the rules in [[over.match]](over.match "12.2 Overload resolution")[.](#1.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
The postfix expression shall
|
||||
have function type or function pointer type[.](#1.sentence-3)
|
||||
|
||||
For a call to a non-member function or to a static member function,
|
||||
the postfix expression shall be either an lvalue that refers to a
|
||||
function (in which case the function-to-pointer standard
|
||||
conversion ([[conv.func]](conv.func "7.3.4 Function-to-pointer conversion")) is suppressed on the postfix expression),
|
||||
or a prvalue of function pointer type[.](#1.sentence-4)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3770)
|
||||
|
||||
If the selected
|
||||
function is non-virtual, or if the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") in the class
|
||||
member access expression is a [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]"), that function is
|
||||
called[.](#2.sentence-1)
|
||||
|
||||
Otherwise, its [final overrider](class.virtual#def:final_overrider "11.7.3 Virtual functions [class.virtual]") in the dynamic type
|
||||
of the object expression is called; such a call is referred to as a[*virtual function call*](#def:function,virtual_function_call "7.6.1.3 Function call [expr.call]")[.](#2.sentence-2)
|
||||
|
||||
[*Note [2](#note-2)*:
|
||||
|
||||
The dynamic type is the type of the object referred to by the
|
||||
current value of the object expression[.](#2.sentence-3)
|
||||
|
||||
[[class.cdtor]](class.cdtor "11.9.5 Construction and destruction") describes the
|
||||
behavior of virtual function calls when the object expression
|
||||
refers to
|
||||
an object under construction or destruction[.](#2.sentence-4)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3785)
|
||||
|
||||
[*Note [3](#note-3)*:
|
||||
|
||||
If a function or member function name is used, and [name
|
||||
lookup](basic.lookup "6.5 Name lookup [basic.lookup]") does not find a declaration of that name,
|
||||
the program is ill-formed[.](#3.sentence-1)
|
||||
|
||||
No function is implicitly declared by such a
|
||||
call[.](#3.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3793)
|
||||
|
||||
If the [*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1 General [expr.post.general]") names
|
||||
a destructor or pseudo-destructor ([[expr.prim.id.dtor]](expr.prim.id.dtor "7.5.5.5 Destruction")),
|
||||
the type of the function call expression is void; otherwise, the
|
||||
type of the function call expression is the return type of the
|
||||
statically chosen function (i.e., ignoring the virtual keyword),
|
||||
even if the type of the function actually called is different[.](#4.sentence-1)
|
||||
|
||||
If the [*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1 General [expr.post.general]") names a pseudo-destructor
|
||||
(in which case the [*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1 General [expr.post.general]") is a possibly-parenthesized class member access),
|
||||
the function call destroys
|
||||
the object of scalar type
|
||||
denoted by the object expression
|
||||
of the class member access ([[expr.ref]](expr.ref "7.6.1.5 Class member access"), [[basic.life]](basic.life "6.8.4 Lifetime"))[.](#4.sentence-2)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3809)
|
||||
|
||||
A type Tcall is[*call-compatible*](#def:call-compatible "7.6.1.3 Function call [expr.call]") with a function type Tfunc if Tcall is the same type as Tfunc or
|
||||
if the type âpointer to Tfuncâ can be
|
||||
converted to type âpointer to Tcallâ
|
||||
via a function pointer conversion ([[conv.fctptr]](conv.fctptr "7.3.14 Function pointer conversions"))[.](#5.sentence-1)
|
||||
|
||||
Calling a function through an
|
||||
expression whose function type
|
||||
is not call-compatible with the
|
||||
type of the called function's
|
||||
definition results in undefined behavior[.](#5.sentence-2)
|
||||
|
||||
[*Note [4](#note-4)*:
|
||||
|
||||
This requirement allows the case
|
||||
when the expression has the type of a
|
||||
potentially-throwing function, but the called function has
|
||||
a non-throwing exception specification,
|
||||
and the function types are otherwise the same[.](#5.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3829)
|
||||
|
||||
When a function is called, each parameter ([[dcl.fct]](dcl.fct "9.3.4.6 Functions")) is
|
||||
initialized ([[dcl.init]](dcl.init "9.5 Initializers"), [[class.copy.ctor]](class.copy.ctor "11.4.5.3 Copy/move constructors")) with
|
||||
its corresponding argument,
|
||||
and each precondition assertion of the function
|
||||
is evaluated ([[dcl.contract.func]](dcl.contract.func "9.4.1 General"))[.](#6.sentence-1)
|
||||
|
||||
If the function is an explicit object member function and
|
||||
there is an implied object argument ([[over.call.func]](over.call.func "12.2.2.2.2 Call to designated function")),
|
||||
the list of provided arguments is preceded by the implied object argument
|
||||
for the purposes of this correspondence[.](#6.sentence-2)
|
||||
|
||||
If there is no corresponding argument,
|
||||
the default argument for the parameter is used[.](#6.sentence-3)
|
||||
|
||||
[*Example [1](#example-1)*: template<typename ...T> int f(int n = 0, T ...t);int x = f<int>(); // error: no argument for second function parameter â *end example*]
|
||||
|
||||
If the function is an implicit object member
|
||||
function,
|
||||
the object expression of the class member access shall be a glvalue and
|
||||
the implicit object parameter of the function ([[over.match.funcs]](over.match.funcs "12.2.2 Candidate functions and argument lists"))
|
||||
is initialized with that glvalue,
|
||||
converted as if by an [explicit type conversion](expr.cast "7.6.3 Explicit type conversion (cast notation) [expr.cast]")[.](#6.sentence-4)
|
||||
|
||||
[*Note [5](#note-5)*:
|
||||
|
||||
There is no access or ambiguity checking on this conversion; the access
|
||||
checking and disambiguation are done as part of the (possibly implicit)
|
||||
class member access operator[.](#6.sentence-5)
|
||||
|
||||
See [[class.member.lookup]](class.member.lookup "6.5.2 Member name lookup"), [[class.access.base]](class.access.base "11.8.3 Accessibility of base classes and base class members"),
|
||||
and [[expr.ref]](expr.ref "7.6.1.5 Class member access")[.](#6.sentence-6)
|
||||
|
||||
â *end note*]
|
||||
|
||||
When a function is called, the type of any parameter
|
||||
shall not be a class type that is either incomplete or abstract[.](#6.sentence-7)
|
||||
|
||||
[*Note [6](#note-6)*:
|
||||
|
||||
This still allows a parameter to be a pointer or reference to such
|
||||
a type[.](#6.sentence-8)
|
||||
|
||||
However, it prevents a passed-by-value parameter
|
||||
to have an incomplete or abstract class type[.](#6.sentence-9)
|
||||
|
||||
â *end note*]
|
||||
|
||||
It is implementation-defined
|
||||
whether a parameter is destroyed
|
||||
when the function in which it is defined exits ([[stmt.return]](stmt.return "8.8.4 The return statement"), [[except.ctor]](except.ctor "14.3 Stack unwinding"), [[expr.await]](expr.await "7.6.2.4 Await"))
|
||||
or at the end of the enclosing full-expression;
|
||||
parameters are always destroyed in the reverse order of their construction[.](#6.sentence-10)
|
||||
|
||||
The initialization and destruction of each parameter occurs
|
||||
within the context of the full-expression ([[intro.execution]](intro.execution "6.10.1 Sequential execution"))
|
||||
where the function call appears[.](#6.sentence-11)
|
||||
|
||||
[*Example [2](#example-2)*:
|
||||
|
||||
The access ([[class.access.general]](class.access.general "11.8.1 General")) of the
|
||||
constructor, conversion functions, or destructor is
|
||||
checked at the point of call[.](#6.sentence-12)
|
||||
|
||||
If a constructor
|
||||
or destructor for a function parameter throws an exception,
|
||||
any [*function-try-block*](except.pre#nt:function-try-block "14.1 Preamble [except.pre]") ([[except.pre]](except.pre "14.1 Preamble"))
|
||||
of the called function
|
||||
with a handler that can handle the exception
|
||||
is not considered[.](#6.sentence-13)
|
||||
|
||||
â *end example*]
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3890)
|
||||
|
||||
The [*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1 General [expr.post.general]") is sequenced before
|
||||
each [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") in the [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1 General [expr.post.general]") and any default argument[.](#7.sentence-1)
|
||||
|
||||
The initialization of a parameter or,
|
||||
if the implementation introduces any temporary objects
|
||||
to hold the values of function parameters ([[class.temporary]](class.temporary "6.8.7 Temporary objects")),
|
||||
the initialization of those temporaries,
|
||||
including every associated value computation and side effect,
|
||||
is indeterminately sequenced with respect to that of any other parameter[.](#7.sentence-2)
|
||||
|
||||
These evaluations are
|
||||
sequenced before
|
||||
the evaluation of the precondition assertions of the function,
|
||||
which are evaluated in sequence ([[dcl.contract.func]](dcl.contract.func "9.4.1 General"))[.](#7.sentence-3)
|
||||
|
||||
For any temporaries
|
||||
introduced to hold the values of function parameters,
|
||||
the initialization of the parameter objects from those temporaries
|
||||
is indeterminately sequenced with respect to
|
||||
the evaluation of each precondition assertion[.](#7.sentence-4)
|
||||
|
||||
[*Note [7](#note-7)*:
|
||||
|
||||
All side effects of
|
||||
argument evaluations are sequenced before the function is
|
||||
entered (see [[intro.execution]](intro.execution "6.10.1 Sequential execution"))[.](#7.sentence-5)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[*Example [3](#example-3)*: void f() { std::string s = "but I have heard it works even if you don't believe in it";
|
||||
s.replace(0, 4, "").replace(s.find("even"), 4, "only").replace(s.find(" don't"), 6, "");
|
||||
assert(s == "I have heard it works only if you believe in it"); // OK} â *end example*]
|
||||
|
||||
[*Note [8](#note-8)*:
|
||||
|
||||
If an operator function is invoked
|
||||
using operator notation,
|
||||
argument evaluation is sequenced
|
||||
as specified for the built-in operator;
|
||||
see [[over.match.oper]](over.match.oper "12.2.2.3 Operators in expressions")[.](#7.sentence-6)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[*Example [4](#example-4)*: struct S { S(int);};int operator<<(S, int);int i, j;int x = S(i=1) << (i=2);int y = operator<<(S(j=1), j=2);
|
||||
|
||||
After performing the initializations,
|
||||
the value of i is 2 (see [[expr.shift]](expr.shift "7.6.7 Shift operators")),
|
||||
but it is unspecified whether the value of j is 1 or 2[.](#7.sentence-7)
|
||||
|
||||
â *end example*]
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3948)
|
||||
|
||||
The result of a function call is the result of the possibly-converted operand
|
||||
of the return statement ([[stmt.return]](stmt.return "8.8.4 The return statement"))
|
||||
that transferred control out of the called function (if any),
|
||||
except in a virtual function call if the return type of the
|
||||
final overrider is different from the return type of the statically
|
||||
chosen function, the value returned from the final overrider is
|
||||
converted to the return type of the statically chosen function[.](#8.sentence-1)
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3957)
|
||||
|
||||
When the called function exits normally ([[stmt.return]](stmt.return "8.8.4 The return statement"), [[expr.await]](expr.await "7.6.2.4 Await")),
|
||||
all postcondition assertions of the function
|
||||
are evaluated in sequence ([[dcl.contract.func]](dcl.contract.func "9.4.1 General"))[.](#9.sentence-1)
|
||||
|
||||
If the implementation introduces any temporary objects
|
||||
to hold the result value as specified in [[class.temporary]](class.temporary "6.8.7 Temporary objects"),
|
||||
the evaluation of each postcondition assertion
|
||||
is indeterminately sequenced with respect to
|
||||
the initialization of any of those temporaries or the result object[.](#9.sentence-2)
|
||||
|
||||
These evaluations, in turn, are sequenced before
|
||||
the destruction of any function parameters[.](#9.sentence-3)
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3969)
|
||||
|
||||
[*Note [9](#note-9)*:
|
||||
|
||||
A function can change the values of its non-const parameters, but these
|
||||
changes cannot affect the values of the arguments except where a
|
||||
parameter is of a reference type ([[dcl.ref]](dcl.ref "9.3.4.3 References")); if the reference is to
|
||||
a const-qualified type, const_cast needs to be used to
|
||||
cast away the constness in order to modify the argument's value[.](#10.sentence-1)
|
||||
|
||||
Where a
|
||||
parameter is of const reference type a temporary object is
|
||||
introduced if
|
||||
needed ([[dcl.type]](dcl.type "9.2.9 Type specifiers"), [[lex.literal]](lex.literal "5.13 Literals"), [[lex.string]](lex.string "5.13.5 String literals"), [[dcl.array]](dcl.array "9.3.4.5 Arrays"), [[class.temporary]](class.temporary "6.8.7 Temporary objects"))[.](#10.sentence-2)
|
||||
|
||||
In addition, it is possible to modify the values of non-constant objects through
|
||||
pointer parameters[.](#10.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3989)
|
||||
|
||||
A function can be declared to accept fewer arguments (by declaring [default
|
||||
arguments](dcl.fct.default "9.3.4.7 Default arguments [dcl.fct.default]")) or more arguments (by using the ellipsis,..., or a function parameter pack ([[dcl.fct]](dcl.fct "9.3.4.6 Functions"))) than the number of
|
||||
parameters in the [function definition](dcl.fct.def "9.6 Function definitions [dcl.fct.def]")[.](#11.sentence-1)
|
||||
|
||||
[*Note [10](#note-10)*:
|
||||
|
||||
This implies that, except where the ellipsis (...) or a function
|
||||
parameter pack is used, a parameter is available for each argument[.](#11.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[12](#12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L4001)
|
||||
|
||||
When there is no parameter for a given argument, the argument is passed
|
||||
in such a way that the receiving function can obtain the value of the
|
||||
argument by invoking va_arg ([[support.runtime]](support.runtime "17.14 Other runtime support"))[.](#12.sentence-1)
|
||||
|
||||
[*Note [11](#note-11)*:
|
||||
|
||||
This paragraph does not apply to arguments passed to a function parameter pack[.](#12.sentence-2)
|
||||
|
||||
Function parameter packs are expanded during template instantiation ([[temp.variadic]](temp.variadic "13.7.4 Variadic templates")),
|
||||
thus each such argument has a corresponding parameter when a function template
|
||||
specialization is actually called[.](#12.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
|
||||
The[lvalue-to-rvalue](conv.lval "7.3.2 Lvalue-to-rvalue conversion [conv.lval]"), [array-to-pointer](conv.array "7.3.3 Array-to-pointer conversion [conv.array]"),
|
||||
and [function-to-pointer](conv.func "7.3.4 Function-to-pointer conversion [conv.func]") standard conversions are
|
||||
performed on the argument expression[.](#12.sentence-4)
|
||||
|
||||
An argument that has type cv std::nullptr_t is converted
|
||||
to type void* ([[conv.ptr]](conv.ptr "7.3.12 Pointer conversions"))[.](#12.sentence-5)
|
||||
|
||||
After these conversions, if the
|
||||
argument does not have arithmetic, enumeration, pointer, pointer-to-member,
|
||||
or class type, the program is ill-formed[.](#12.sentence-6)
|
||||
|
||||
Passing a potentially-evaluated argument
|
||||
of a scoped enumeration type ([[dcl.enum]](dcl.enum "9.8.1 Enumeration declarations")) or
|
||||
of a class type ([[class]](class "11 Classes")) having
|
||||
an eligible non-trivial copy constructor ([[special]](special "11.4.4 Special member functions"), [[class.copy.ctor]](class.copy.ctor "11.4.5.3 Copy/move constructors")),
|
||||
an eligible non-trivial move constructor, or
|
||||
a non-trivial destructor ([[class.dtor]](class.dtor "11.4.7 Destructors")),
|
||||
with no corresponding parameter, is conditionally-supported withimplementation-defined semantics[.](#12.sentence-7)
|
||||
|
||||
If the argument has
|
||||
integral or enumeration type that is subject to the [integral
|
||||
promotions](conv.prom "7.3.7 Integral promotions [conv.prom]"), or a floating-point type that is subject to the[floating-point promotion](conv.fpprom "7.3.8 Floating-point promotion [conv.fpprom]"), the value of the argument is converted to the
|
||||
promoted type before the call[.](#12.sentence-8)
|
||||
|
||||
These promotions are referred to as
|
||||
the [*default argument promotions*](#def:promotion,default_argument_promotion "7.6.1.3 Function call [expr.call]")[.](#12.sentence-9)
|
||||
|
||||
[13](#13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L4035)
|
||||
|
||||
Recursive calls are permitted, except to the [main function](basic.start.main "6.10.3.1 main function [basic.start.main]")[.](#13.sentence-1)
|
||||
|
||||
[14](#14)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L4040)
|
||||
|
||||
A function call is an lvalue
|
||||
if the result type is an lvalue reference type or an rvalue reference to function type,
|
||||
an xvalue if the result type is an rvalue reference to object type, and a prvalue
|
||||
otherwise[.](#14.sentence-1)
|
||||
|
||||
If it is a non-void prvalue,
|
||||
the type of the function call expression shall be complete,
|
||||
except as specified in [[dcl.type.decltype]](dcl.type.decltype "9.2.9.6 Decltype specifiers")[.](#14.sentence-2)
|
||||
Reference in New Issue
Block a user