LINUX.ORG.RU

тупые вопросы по C


0

0

Посмотрел man 2 open и только щас заметил что там вроде как две функции open с разным кол-вом аргументов.

1) Смотрю исходник, а там вообще нет "..." при том что va_list используется. Разве так можно?

int __open (const char *file, int oflag) {
  [...]
  if (oflag & O_CREAT)
    {
      va_list arg;
      va_start(arg, oflag);
      mode = va_arg(arg, int);
      va_end(arg);
    }
  [...]
}

2) Как одна функция(враппер) с переменным кол-вом аргументов может вызвать другую функцию со всеми своими параметрами? Или это в принципе не возможно и нужна версия функции которая принимает va_list(типа printf и vprintf)?

★★★★★

> Или это в принципе не возможно и нужна версия функции которая принимает va_list(типа printf и vprintf)?

В двух словах - да, на C это невозможно, нужна дублирующая функция, принимающая va_list.

Dendy ★★★★★
()
Ответ на: комментарий от edigaryev

фак, я что-то не то нарыл. Ну да ладно, вопрос всё равно интересный, можно ли не писать ... и при этом va_start вызывать.

А ещё интересно можно ли его вообще не вызывать и будет ли что за это.

true_admin ★★★★★
() автор топика

только щас заметил что там вроде как две функции open с разным кол-вом аргументов.

Мне кажется это специально сделано, чтобы не запутывать читателя. Функция же на самом деле одна, но в одном случае она может принимать аргумент mode, а может и не принимать (если такой аргумент не передается).

edigaryev ★★★★★
()
Ответ на: комментарий от edigaryev

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

Сам дурак, знаю :).

true_admin ★★★★★
() автор топика
Ответ на: комментарий от true_admin

можно ли не писать ... и при этом va_start вызывать

Как бы можно не писать, если убедишь компилятор вызвать с лишними параметрами. Но на некоторых типах аргументов (float, short) не сработает - там в случае необязательных параметров делается promoting, и va_* на это рассчитывают.

можно ли его вообще не вызывать

Конечно можно.

unsigned ★★★★
()
Ответ на: комментарий от true_admin

можно ли не писать ... и при этом va_start вызывать.

$ cat test.c 
#include <stdio.h>
#include <stdarg.h>

void magic(int arg1, int arg2);

int main(void) {
	magic(1,2,3);
	return 0;
}

void magic(int arg1, int arg2) {
	int tmp;
	va_list ap;
	va_start(ap,arg2);
	tmp = va_arg(ap,int);
	va_end(ap);
	printf("arg1: %d\narg2: %d\ntmp: %d\n",arg1,arg2,tmp);
}
$ gcc -o test test.c
test2.c: In function ‘main’:
test2.c:7: error: too many arguments to function ‘magic’
test2.c: In function ‘magic’:
test2.c:14: error: ‘va_start’ used in function with fixed args
edigaryev ★★★★★
()
Ответ на: комментарий от edigaryev

С двумя исключениями: прототип без аргументов (int func(), в целях совместимости, правильно объявлять функцию без параметров как int func(void)) и прототип с переменным кол-вом аргументов, если в определении указаны только фиксированные аргументы.

kemm
()
Ответ на: комментарий от edigaryev

> Но ведь объявление функции и её прототип должны совпадать?!

Это тебе кто сказал? Напоминаю, речь идёт о С. ;)

LamerOk ★★★★★
()
Ответ на: комментарий от legolegs

Мы не говорим о С++, мы говорим о С, причем это будет верно для любого С, как K&R, так и С99.

LamerOk ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.