В C эти типы не совместимы.
В разделе 6.2.7 стандарта C , касающемся «Совместимого типа и составного типа», говорится следующее относительносовместимость указателей функций:
3 Составной тип может быть составлен из двух совместимых типов;это тип, который совместим с обоими этими двумя типами и удовлетворяет следующим условиям:
- Если оба типа являются типами массивов, применяются следующие правила:
- Если один типявляется массивом известного постоянного размера, составной тип является массивом этого размера.
- В противном случае, если один тип является массивом переменной длины, размер которого определяется выражением, которое не оценивается, поведение не определено.
- В противном случае, если один тип является массивом переменной длины, размер которого указан, составной тип является массивом переменной длины этого размера.
- В противном случае, если один тип является массивом переменной длиныс неопределенным размером, составной тип является массивом переменной длины неопределенного размера.
- В противном случае оба типа являются массивами неизвестного размера, а составной тип является массивом неизвестного размера.Тип элемента составного типа - это составной тип двух типов элементов.
- Если только один тип является типом функции со списком типов параметров (прототип функции)составной тип - это прототип функции со списком типов параметров.
- Если оба типа являются типами функций со списками типов параметров, тип каждого параметра в списке составных типов параметров - этосоставной тип соответствующих параметров.
...
5 ПРИМЕР С учетом следующих двух деклараций области действия файла:
int f(int (*)(), double (*)[3]);
int f(int (*)(char *), double (*)[]);
Результирующий составной тип для функции:
int f(int (*)(char *), double (*)[3]);
В разделе 6.7.6.3p15 указано:
Для совместимости двух типов функций оба должныуказать совместимые типы возврата. Кроме того, списки типов параметров, если присутствуют оба, должны согласовываться по количеству параметров и при использовании терминатора эллипса; соответствующие параметры должны иметь совместимые типы.Если один тип имеет список типов параметров, а другой тип указывается декларатором функции, который не является частью определения функции и содержит пустой список идентификаторов, список параметров не должен иметь терминатора с многоточием и тип каждого параметра долженбыть совместимым с типом, который является результатом применения продвижения аргумента по умолчанию.Если один тип имеет список типов параметров, а другой тип определен в определении функции, которое содержит (возможно, пустой) список идентификаторов, оба должны совпадать по количеству параметров, и тип каждого параметра прототипа должен быть совместим с типомэто является результатом применения продвижения аргумента по умолчанию к типу соответствующего идентификатора.(При определении совместимости типов и составного типа каждый параметр, объявленный с типом функции или массива, принимается как имеющий скорректированный тип, а каждый параметр, объявленный с квалифицированным типом, принимается как имеющий неквалифицированную версию своего объявленного типа.)
В вашем примере:
int test(int, ...);
Эта функция совместима со следующими функциями:
int (*)(); // a function taking an unknown number of parameters and returns an int
int (*)(int, ...); // a function taking an int and variable parameters after and returns an int
Но не:
int (*)(int, int, long); // a function taking an int, an int, and a long, and returns an int
Поскольку оба типа функций задают список параметров, а также потому, что количество параметров и использование многоточия не совпадают, типы несовместимы. Попытка вызова функции через несовместимый указатель вызывает неопределенное поведение согласно разделу 6.3.2.3p8:
Указатель на функцию одного типа может быть преобразован в указатель на
функция другого типа и обратно; результат должен сравниться
равно оригинальному указателю. Если для вызова используется преобразованный указатель
функция, тип которой не совместим с указанным типом,
поведение не определено.