Может ли неименованный параметр функции иметь значение по умолчанию?

Является ли следующий код законным в С++?

void f(void* = 0)
{}

int main()
{
    f();
}

Какая страница стандарта С++ заявляет, что это использование является законным?

Ответ 1

Да, это законно.

Нет стандартных формулировок, позволяющих конкретно использовать эту комбинацию функций; просто не запрещается это делать.

Синтаксис аргумента по умолчанию применяется к параметрам функции в объявлении параметра:

[C++11: 8.3.6/1]: Если в объявлении параметра указано предложение initializer, это предложение initializer используется как аргумент по умолчанию. Аргументы по умолчанию будут использоваться в вызовах, в которых отсутствуют отсутствующие аргументы.

... и параметры функции в объявлении параметра могут быть неназванными:

[C++11: 8.3.5/11]: [..] Идентификатор может содержать необязательно в качестве имени параметра. [..]

Существует даже пример этого использования в разделе 8.3.6/4 (хотя примеры не являются нормативным текстом, поэтому это не может быть использовано для доказательства чего-либо конкретно).

Ответ 2

Да, это совершенно законно. Очевидный пример приведен в N3485 8.3.6 Аргументы по умолчанию/4:

[Пример: объявление

void point(int = 3, int = 4);  

объявляет функцию, которая может быть вызвана с нулевым, одним или двумя аргументами типа int.

Ответ 3

Да, это законно.
Синтаксические представления, заданные для параметров функции в разделе 8.3.5/1, допускают объявление параметра без идентификатора, но с выражением присваивания (как инициализатор).

Ответ 4

Это не только законно, но и может быть весьма полезным в зависимости от стиля кодирования.

Параметры по умолчанию имеют смысл только в объявлении функции.

Именованные параметры имеют смысл только в определении функции.

f.h:

void f(void*=nullptr);

f.cc

void f(void* x)
{
...
}