Можно ли переносимо определить функцию, которая принимает любое количество аргументов? - PullRequest
1 голос
/ 16 марта 2011

У меня есть смутное понимание того, что означает «переносимость C» (IIRC, это означает, что язык C охватывает несколько платформ, но он должен придерживаться определенных стандартов (?)) И хотел бы знать, можем ли мы писать программы, которые переносимы примет любое количество аргументов (даже ни одного).

Что я знаю, так это то, что без учета переносимости все функции, написанные с пустой парой скобок '()', могут принимать x-количество аргументов, но что с этим? Кажется, что есть несколько статей о поощряющих ограничениях в отношении количества аргументов, принимаемых переносимо определенными функциями, но мне еще предстоит найти такой, который говорит, что мы не можем передать x-количество аргументов (где x не ограничено).

Ответы [ 2 ]

3 голосов
/ 16 марта 2011
  • функция определена с пустым набором скобок:

    void f () {...}

не принимает параметры, и вызывать его с любым не определено.

  • функция объявлена ​​ с пустым набором скобок:

    void g ();

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

  • , чтобы объявить функцию без параметров (и, таким образом, получить сообщение об ошибке, если вы запутались), используйте

    void g (void);

  • функция может быть переменной, но для ее вызова вы должны увидеть объявление о том, что функция является переменной:

    void h (int nb, ...);

(Не то чтобы в C функция с переменными значениями должна иметь хотя бы один невариационный параметр, в C ++ это не так)

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

-

Чтобы устранить путаницу:

void f() { ... }

против

void g(void) { ... }

f определяется как не принимающий параметры и не может быть вызван ни с каким параметром, объявленным как принимающий неизвестное количество параметров, поэтому компилятор не будет гарантировать, что никакие параметры не заданы. g определен и объявлен как принимающий никаких параметров. Это осталось дней K & R с определениями функций, такими как

int h()
    int i;
{...}

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

2 голосов
/ 16 марта 2011

Использование <stdarg.h>.

См., Например, раздел 15, вопрос 4 C-FAQ .


Редактировать : пример использования stdarg.h>

#include <stdarg.h>
#include <stdio.h>

/* sum all values (no overflow checking) up to a 0 (zero) */
int sum(int v, ...) {
  va_list va;
  int s = v;
  if (v) {
    va_start(va, v);
    while ((v = va_arg(va, int))) {
      s += v;
    }
    va_end(va);
  }
  return s;
}

int main(void) {
  printf("sum(5, 4, 6, 10) is %d\n", sum(5, 4, 6, 10, 0));
  return 0;
}
...