[expr.call] (original) (raw)

7 Expressions [expr]

7.6 Compound expressions [expr.compound]

7.6.1 Postfix expressions [expr.post]

7.6.1.2 Function call [expr.call]

A function call is a postfix expression followed by parentheses containing a possibly empty, comma-separated list ofinitializer-clauses which constitute the arguments to the function.

[ Note

:

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].

end note

]

The postfix expression shall have function type or function pointer type.

For a call to a non-member function or to a static member function, the postfix expression shall either be an lvalue that refers to a function (in which case the function-to-pointer standard conversion ([conv.func]) is suppressed on the postfix expression), or have function pointer type.

In the case of an implicit class member access, the implied object is the one pointed to by this.

If the selected function is non-virtual, or if the id-expression in the class member access expression is a qualified-id, that function is called.

Otherwise, its final overrider in the dynamic type of the object expression is called; such a call is referred to as avirtual function call.

[ Note

:

The dynamic type is the type of the object referred to by the current value of the object expression.

[class.cdtor] describes the behavior of virtual function calls when the object expression refers to an object under construction or destruction.

end note

]

[ Note

:

If a function or member function name is used, and name lookup does not find a declaration of that name, the program is ill-formed.

No function is implicitly declared by such a call.

end note

]

If the postfix-expression names a destructor or pseudo-destructor ([expr.prim.id.dtor]), 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.

This return type shall be an object type, a reference type or cv void.

If the postfix-expression names a pseudo-destructor (in which case the postfix-expressionis 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], [basic.life]).

Calling a function through an expression whose function type is different from the function type of the called function's definition results in undefined behavior.

If there is no corresponding argument, the default argument for the parameter is used.

[ Example

:

template<typename ...T> int f(int n = 0, T ...t); int x = f();

end example

]

If the function is a non-static member function, the this parameter of the function is initialized with a pointer to the object of the call, converted as if by an explicit type conversion.

[ Note

:

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.

end note

]

When a function is called, the type of any parameter shall not be a class type that is either incomplete or abstract.

[ Note

:

This still allows a parameter to be a pointer or reference to such a type.

However, it prevents a passed-by-value parameter to have an incomplete or abstract class type.

end note

]

It is implementation-defined whether the lifetime of a parameter ends when the function in which it is defined returns or at the end of the enclosing full-expression.

The initialization and destruction of each parameter occurs within the context of the calling function.

[ Example

:

The access of the constructor, conversion functions or destructor is checked at the point of call in the calling function.

If a constructor or destructor for a function parameter throws an exception, the search for a handler starts in the scope of the calling function; in particular, if the function called has a function-try-blockwith a handler that could handle the exception, this handler is not considered.

end example

]

The initialization of a parameter, including every associated value computation and side effect, is indeterminately sequenced with respect to that of any other parameter.

[ Note

:

All side effects of argument evaluations are sequenced before the function is entered (see [intro.execution]).

end note

]

[ Example

:

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");
}

end example

]

[ Note

:

If an operator function is invoked using operator notation, argument evaluation is sequenced as specified for the built-in operator; see [over.match.oper].

end note

]

[ Example

:

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]), but it is unspecified whether the value of j is 1 or 2.

end example

]

The result of a function call is the result of the possibly-converted operand of the return statementthat 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.

[ Note

:

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]); if the reference is to a const-qualified type, const_­cast is required to be used to cast away the constness in order to modify the argument's value.

In addition, it is possible to modify the values of non-constant objects through pointer parameters.

end note

]

A function can be declared to accept fewer arguments (by declaring default arguments) or more arguments (by using the ellipsis,..., or a function parameter pack ([dcl.fct])) than the number of parameters in the function definition.

[ Note

:

This implies that, except where the ellipsis (...) or a function parameter pack is used, a parameter is available for each argument.

end note

]

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.

[ Note

:

This paragraph does not apply to arguments passed to a function parameter pack.

Function parameter packs are expanded during template instantiation ([temp.variadic]), thus each such argument has a corresponding parameter when a function template specialization is actually called.

end note

]

An argument that has type cv std​::​nullptr_­t is convertedto type void*.

After these conversions, if the argument does not have arithmetic, enumeration, pointer, pointer-to-member, or class type, the program is ill-formed.

Passing a potentially-evaluated argument of a scoped enumeration type or of a class type ([class]) having an eligible non-trivial copy constructor, an eligible non-trivial move constructor, or a non-trivial destructor ([special]), with no corresponding parameter, is conditionally-supported withimplementation-defined semantics.

If the argument has integral or enumeration type that is subject to the integral promotions, or a floating-point type that is subject to thefloating-point promotion, the value of the argument is converted to the promoted type before the call.

These promotions are referred to as the default argument promotions.

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.