Почему я могу вызвать функцию через указатель со слишком большим количеством аргументов?

Скажем, у меня есть эта функция:

int func2() {
    printf("func2\n");
    return 0;
}

Теперь я объявляю указатель:

int (*fp)(double);

Это должно указывать на функцию, которая принимает double аргумент и возвращает int,

func2 не имеет никаких аргументов, но все же, когда я пишу:

fp = func2;
fp(2);

2 будучи просто произвольным числом), func2` вызывается правильно.

Это почему? Разве нет смысла в количестве параметров, которые я объявляю для указателя функции?

2 ответа

Решение

Да, в этом есть смысл. В C (но не в C++) функция, объявленная с пустым набором скобок, означает, что она принимает неопределенное количество параметров. Когда вы делаете это, вы не позволяете компилятору проверять количество и типы аргументов; это пережиток до того, как язык C был стандартизирован ANSI и ISO.

Неспособность вызвать функцию с правильным числом и типами аргументов приводит к неопределенному поведению. Если вы вместо этого явно объявите свою функцию, чтобы принять нулевые параметры, используя список параметров voidтогда компилятор выдаст вам предупреждение, когда вы назначите указатель на функцию неправильного типа:

int func1();  // declare function taking unspecified parameters
int func2(void);  // declare function taking zero parameters
...
// No warning, since parameters are potentially compatible; calling will lead
// to undefined behavior
int (*fp1)(double) = func1;
...
// warning: assignment from incompatible pointer type
int (*fp2)(double) = func2;

Вам нужно явно объявить параметр, иначе вы получите неопределенное поведение:)

int func2(double x)
{
    printf("func2(%lf)\n", x);
    return 0;
}
Другие вопросы по тегам