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

Перегрузка функций в C

Сегодня, глядя на страницу руководства для open(), я заметил, что эта функция "перегружена":

   int open(const char *pathname, int flags);
   int open(const char *pathname, int flags, mode_t mode);

Я не думал, что это возможно на C. Какой "трюк" для достижения этого?

ПОСЛЕДНИЕ ИЗМЕНЕНИЯ:
Поэтому он не перегружает, потому что при использовании varargs вы можете предоставить только несколько аргументов одного типа. Итак, mode_t за кулисами int?

4b9b3361

Ответ 1

Он использует переменные аргументы. Эти объявления появляются только на странице руководства, так как эти 2 являются единственными способами, которые вы должны вызвать open(). Фактическая функция C будет объявлена, например,

int open(const char *pathname,int flags,...);

С переменными аргументами аргументы не должны быть одного типа. printf - очевидный пример этого.

В случае open() первый переменный аргумент должен быть mode_t, если 'flags содержит флаг O_CREAT, потому что реализация open() ожидает, что он будет mode_t (который за кулисами, скорее всего, представляет собой unsigned int или unsigned long - но это не имеет ничего общего с varargs)

Ответ 2

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

С учетом сказанного, нет надежного кросс-платформенного способа в C, чтобы написать функцию, которая принимает ровно 2 или 3 аргумента; в общем, вы должны сделать что-то вроде

some_function(5, 6, 7, NULL);
some_function(5, 6, 8, 2, 5, NULL);

Другими словами, у вас должен быть завершающий "отважный" аргумент. В качестве альтернативы вы можете указать количество параметров как-то в более раннем параметре, например

another_func(2, "hello", "world");
another_func(3, "goodbye", "cruel", "world");

Семейство функций printf принимает такой подход; первый параметр формата содержит необходимое количество дополнительных параметров; например с printf("%f %f", 5.6, 7.11) вы знаете, что должно быть 2 параметра float. Однако это будет несколько небезопасно в пользовательской библиотечной функции, так как если бы вы сказали my_printf("%s %f %f %f %s", 5.6), тогда вы могли бы получить segfaults или еще хуже. К счастью, большинство компиляторов C будут проверять ваши вызовы на printf во время компиляции, чтобы избежать такой проблемы.

В случае open функция объявляется как имеющая переменные аргументы, а третий параметр проверяется только при установке O_CREAT. Так вот как он "безопасно" определяет, присутствует ли третий аргумент. Я положил "безопасно" в кавычки, потому что технически нет возможности открывать для себя во время выполнения, сколько параметров было фактически передано. Например, следующие вызовы будут компилироваться без каких-либо ошибок или предупреждений:

open("foo.txt", 5, "not an integer", 7);    // extra and invalid parameters
open("bar.txt", O_CREAT);                   // third parameter is missing

Ответ 3

"должен указываться, когда O_CREAT находится во флагах и в противном случае игнорируется."

extern int open (__const char *__file, int __oflag, ...)

Он использует varargs и загружает только аргумент переменной режима, если __oflag содержит O_CREAT.

Ответ 4

очень короткий ответ - varargs

Ответ 5

вы можете подделать его с помощью списка переменных аргументов с помощью ...

int function(int x, ...);