Почему дополнительная запятая не разрешена в списке параметров, когда она разрешена в инициализации скобки?

Следуя моему старому вопросу (Есть ли какое-либо отношение к добавочному "," в конце инициализации скобки?)

Существуют ли какие-либо технические причины, по которым список параметров в объявлениях функций и вызовах функций не был создан для генерации кода, как инициализация скобки?

Что я имею в виду:

Это нормально, дополнительный , игнорируется:

int generated_array[] = {
  1,
  2,
  3,
};

Для согласованности, не имеет ли смысл это допускать?

int someFunc(
  int v1,
  int v2,
  int v3,
){...}

int ret_val = someFunc(
  1,
  2,
  3,
);

Я не вижу, как это усложнит компиляцию, но, возможно, есть что-то, о чем я не думаю. Я бы предположил, что это немного упростит его.

Конечно, можно утверждать, что это не так полезно, как инициализация скобки, но должны быть случаи, когда генерация кода была бы сделана хотя бы чуть-чуть проще, если бы это было разрешено.

Ответ 1

Обоснование конечных запятых в списках инициализаторов - это упрощение машинной генерации больших статических массивов. Таким образом, если вам нужно написать программу, которая генерирует список инициализаторов массива C, вы можете просто написать что-то вроде этого:

printf("int arr[] = {");
for (int i = 0; i < N; i++) {
    printf("%d, ", i);
}
printf("};");

Если конечная запятая не была разрешена, вам нужно убедиться, что она не сгенерирована; и, честно говоря, пока это не сложно сделать, это просто уродливо и боль в шее.

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

Ответ 2

Мы можем найти логическое обоснование для предоставления конечной запятой в списке инициализаторов в Обоснование для языков международного стандартного программирования-C, в котором говорится:

K & R допускает конечную запятую в инициализаторе в конце инициализатора-лист. Стандарт сохранил этот синтаксис, поскольку он обеспечивает гибкость при добавлении или удалении членов из инициализатора список и упрощает создание таких списков.

Это обоснование не применяется к другим случаям.

Это обсуждение comp.lang.c++.moderated: Разделяются ли разделенные запятой списки, заканчивающиеся на запятой legal? также ссылается на то же обоснование.

Ответ 3

В моей точке зрения это связано с тем, что в начале C вы могли вызывать функции до того, как их объявления или функции были объявлены с пустым списком параметров. В этом случае компилятор извлекает информацию о параметрах из вызова функции и ее аргументов. В этом случае конечная запятая может рассматриваться как ошибка, которая была непонятна намерению программиста, который написал вызов, и было неясно, действительно ли функция имеет число параметров, соответствующее количеству аргументов.

Когда вы используете список инициализаторов, вся информация перед вашими глазами. Сколько инициализаторов вы указали так много элементов были инициализированы или так много элементов будут иметь массив.

Ответ 4

Кажется, я помню, что "давным-давно в галактике" синтаксис C разрешал конечную запятую для указания этой функции с переменным числом параметров. Позже он был изменен на синтаксис , ....

Исправьте меня, если я ошибаюсь.