Проблемы с C variadics является то, что они действительно заперты после этого, на самом деле не встроены в языке. Основная проблема заключается в том, что переменные параметры анонимны, у них нет ручек, нет идентификаторов. Это приводит к громоздким макросам VA для генерации ссылок на параметры без имен. Это также приводит к необходимости указывать те макросы, где начинается список вариаций, и какой тип параметров должен иметь.
Вся эта информация действительно должна быть закодирована в правильном синтаксисе самого языка.
Например, можно было бы расширить существующий синтаксис C с формальными параметрами после многоточие, как и
void foo (... int counter, float arglist);
По соглашению, первый параметр может быть для подсчета аргументов, а второй для списка аргументов. Внутри тела функции список можно рассматривать синтаксически как массив.
С таким соглашением вариационные параметры больше не будут анонимными. В теле функции, счетчик может ссылаться, как и любой другой параметр и элементы списка можно ссылаться, как если бы они были массив элементов параметра массива, например, так
void foo (... int counter, float arglist) {
unsigned i;
for (i=0; i<counter; i++) {
printf("list[%i] = %f\n", i, arglist[i]);
}
}
С такой функцией, встроенной в сам язык , каждая ссылка на arglist[i]
затем будет переведена на соответствующие адреса в фрейме стека. Нет необходимости делать это с помощью макросов.
Кроме того, счетчик аргументов автоматически будет вставлен компилятором, что дополнительно уменьшит вероятность ошибки.
Вызов
foo(1.23, 4.56, 7.89);
будет составлен, как если бы она была написана
foo(3, 1.23, 4.56, 7.89);
В теле функции, любой доступ к элементу за пределы фактического числа аргументов фактически переданных может быть проверяются во время выполнения и вызывают сбои во времени компиляции, тем самым значительно повышая безопасность.
И последнее, но не менее важное: все переменные параметры печатаются и могут быть проверены во время компиляции точно так же, как проверены невариантные параметры.
В некоторых случаях было бы желательно иметь чередующиеся типы, например, при записи функции для хранения ключей и значений в коллекции. Это также может быть размещен просто, позволяя более формальные параметры после многоточия, как так
void store (collection dict, ... int counter, key_t key, val_t value);
Эта функция может затем быть названо в качестве
store(dict, key1, val1, key2, val2, key3, val3);
но будет составлен, как если бы она была написана
store(dict, 3, key1, val1, key2, val2, key3, val3);
Типы фактических параметров будут проверять время компиляции на соответствие формальным параметрам.
В теле функции счетчика вновь будет ссылаться по его идентификатору, ключи и значения будет ссылаться как если бы они были массивами,
key[i]
относится к ключу пары ключей г-го/значения value[i]
относится к значению пары i-го значения
, и эти ссылки будут скомпилированы с их соответствующими адресами на фрейме стека.
Ничего из этого действительно трудно сделать, и никогда не было. Однако философия дизайна C просто не способствует таким функциям.
Без углубляясь C компилятор Implementor (или C препроцессора Implementor), принимая на себя ведущую роль в реализации этой или подобной схеме вряд ли мы когда-нибудь увидеть ничего подобного в С.
Беда в том, что люди, которые заинтересованы в безопасности типов и готовы вложить свои работы в свои собственные компиляторы, обычно приходят к выводу, что язык C выходит за рамки спасения, и с самого начала можно начать с более совершенного языка.
Я сам был там, в конце концов решил отказаться от попытки, а затем реализовать один из языков Вирта и добавить к нему безопасные вариации типа. С тех пор я столкнулся с другими людьми, которые рассказали мне о своих собственных прерванных попытках. Правильный тип безопасных вариаций в C, похоже, остается неуловимым.
Если все типы должны быть одного типа, считаете ли вы, что они просто передаются в массив из них? –
Нет встроенного массива в C89. Вы не можете передать, например, 'f ({1,2,3,0})' с компилятором MS C. – mikebloch
вы хотите что-то, что работает с gcc или MS C? Пожалуйста, отметьте соответствующим образом. С C99 существуют решения, которые являются типичными. –