Сегодня, смотря на страницу справочника для open()
, Я заметил, что эта функция 'перегружается':
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
Я не сделал мысли, это возможно на C. Каков 'прием' для достижения этого?
БОЛЕЕ ПОЗДНЕЕ РЕДАКТИРОВАНИЕ:
Таким образом, это действительно не перегружается, потому что при использовании varargs - можно только предоставить несколько аргументов того же типа. Так, mode_t
негласно интервал?
Он использует переменные аргументы . Эти объявления появляются только на странице руководства, так как только эти 2 способа вызвать open (). Фактическая функция C будет объявлена как, например,
int open(const char *pathname,int flags,...);
С переменными аргументами аргументы не обязательно должны быть одного типа. printf
- очевидный пример этого.
В случае open () первый аргумент переменной должен быть mode_t, если ' flags
содержат флаг O_CREAT, потому что реализация open () ожидает, что это будет mode_t (что, скорее всего, негласно беззнаковое целое или беззнаковое длинное - но это не имеет ничего общего с varargs)
вы можете подделать его, используя список переменных аргументов с помощью ...
int function(int x, ...);
«Режим должен быть указан, когда O_CREAT находится в флагах, в противном случае игнорируется.»
extern int open (__const char * __ file, int __oflag, ...)
Он использует varargs
и загружает аргумент переменной режима только в том случае, если __ oflag
содержит O_CREAT
.
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 параметра с плавающей запятой. Однако это было бы несколько небезопасно для пользовательской библиотечной функции, поскольку, если вы укажете my_printf ("% s% f% f% f% s", 5.6)
, тогда вы можете получить segfaults или хуже. К счастью, большинство компиляторов C проверят ваши вызовы printf
во время компиляции, чтобы избежать подобных проблем.
В случае open
функция объявляется как имеющая переменные аргументы, а третий параметр проверяется, только если установлен O_CREAT
. Вот так он «безопасно» определяет, присутствует ли третий аргумент. Я заключил «безопасно» в кавычки, потому что технически open не может узнать во время выполнения, сколько параметров было фактически передано. Например, следующие вызовы будут компилироваться без каких-либо ошибок или предупреждений:
open("foo.txt", 5, "not an integer", 7); // extra and invalid parameters
open("bar.txt", O_CREAT); // third parameter is missing