Skip to content

CWG3054 [expr.call] For which expression forms can default arguments be used? #744

Description

@keinflue

Full name of submitter (unless configured in github; will be published with the issue): Benjamin Sch.

Reference (section label): [expr.call]

Issue description:

It seems unclear what kinds of call expressions can make use of default arguments and there is compiler divergence. Examples:

Accepted by EDG and Clang, rejected by GCC and MSVC (https://godbolt.org/z/PKr36d7zb):

void f(int = 0) {}
int main() { (&f)(); }

Accepted by EDG and MSVC, rejected by GCC and Clang (https://godbolt.org/z/MKTPP6s9d):

void f(int = 0) {}
int main() { (*f)(); }

Accepted by EDG, rejected by MSVC, GCC and Clang (https://godbolt.org/z/PbMjnWj3f):

void f(int = 0) {}
int main() { (0, f)(); }

Accepted by MSVC, rejected by EDG, GCC and Clang (https://godbolt.org/z/zcb4qcThK):

void f(int = 0) {}
int main() { static_cast<void(&)(int)>(f)(); }

Accepted by none, rejected by MSVC, EDG, GCC and Clang (https://godbolt.org/z/97f5dYd1W):

void f(int = 0) {}
int main() { static_cast<void(*)(int)>(f)(); }

The last two examples are potentially useful to distinguish overloads but still be able to use default arguments.

I couldn't find any wording stating when default arguments can be used. As far as I can tell, it is stated unconditionally that they are used in function calls if arguments are missing, but that must clearly be wrong, because it would also allow

void f(int = 0) {}
int main() {
    auto p = f;
    p();
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions