Подтвердить что ты не робот

Comma опущена в объявлении переменной версии в С++

Я использую для объявления вариационных функций, подобных этому:

int f(int n, ...);

При чтении языка программирования С++ я обнаружил, что декларации в книге опускают запятую:

int f(int n...); // the comma has been omitted

Кажется, что этот синтаксис является специфичным для С++, поскольку я получаю эту ошибку, когда пытаюсь ее скомпилировать с помощью компилятора C:

test.c:1:12: error: expected ‘;’, ‘,’ or ‘)’ before ‘...’ token int f(int n...);

Есть ли разница между написанием int f(int n, ...) и int f(int n...)?

Почему в этот синтаксис добавлен С++?

4b9b3361

Ответ 1

Согласно § 8.3.5.4 стандарта С++ (текущий проект):

Где синтаксически корректно и где "..." не является частью абстрактный-декларатор ",..." является синонимом "...".

Короче говоря, в С++ ... (эллипсис) - это сам оператор и поэтому может использоваться без запятой, но использование запятой сохраняется для обратной совместимости.

Ответ 2

В настоящее время обе эти объявления имеют одинаковое значение:

int f(int n, ...);
int f(int n ...);

Это приводит к проблеме, когда следующие два объявления являются законными, но имеют совершенно разные значения:

template <class... T> void f(T...); // function template with parameter pack
template <class T> void f(T...);    // variadic function

Как только С++ 11 вводит вариативные шаблоны, гораздо более вероятно, что второе объявление является ошибкой программиста, а не лениво опуская запятую. В результате было предложено удалить последнее из языка (P0281), но это было очевидно отвергнута.

Ответ 3

С int f(int n, ...); и int f(int n...);, как вы можете см., оба значения , ... и ... имеют то же значение. Comma не обязательна.

Но этот int printz(...); действителен в C++, тогда как int printz(,...); нет (по крайней мере один именованный параметр должен появиться перед параметром многоточия). Вот почему вы можете иметь только (...), хотя аргументы, переданные такой функции, недоступны.

Ответ 4

Как я помню из времени, С++ действительно определил знаки вариационной функции, как вы заметили. Позже быстро развивающийся язык C (в пути от K & R до ANSI) представил прототипы или объявления функций нового стиля, которые также объявили параметры внутри паренс после имени функции. Но с двумя заметными отличиями: запятая перед эллипсами и необходимость мерзости (void) для указания пустого списка параметров (чтобы сохранить обратную совместимость пустых паренов как декларации старого стиля).

Просматривая мои архивы, я нахожу, что оригинальное издание на языке программирования С++ "перепечатано с исправлениями июля 1987 года" показывает:

    <я > аргумент декларирование-лист:
        Arg-декларация-лист <суб > неавтоматического ... opt

    arg-declaration-list:                       ш >         аргумент-декларация

Существует no form, чтобы принять теперь необязательную запятую. Обратите внимание, что список arg-declaration-это разделитель разделяемый, и он не зависает, чтобы предоставить запятую после списка и перед следующей (другой) вещью.

Это самый естественный способ написать это. Если вы хотите запятую, вам нужно явно , ... в первом произведении, как два разных (возможно, разделенных пробелами) токенах.

По мере того, как усилия C по правильной стандартизации прогрессировали, компиляторы С++ начали принимать версии C, а также легко использовать стандартные файлы заголовков C.

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