[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 int f(int n = 0, T ...t);int x = f(); // 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)