Что происходит, если я бросил указатель функции, изменив количество параметров

Я только начинаю переносить голову вокруг указателей функции в C. Понять, как кастинг работ указателей функции, я записал следующую программу. Это в основном создает указатель функции к функции, которая берет один параметр, бросает его к указателю функции с тремя параметрами и вызывает функцию, предоставляя три параметра. Мне было любопытно, что произойдет:

#include 

int square(int val){
  return val*val;
}

void printit(void* ptr){
  int (*fptr)(int,int,int) = (int (*)(int,int,int)) (ptr);
  printf("Call function with parameters 2,4,8.\n");
  printf("Result: %d\n", fptr(2,4,8));
}


int main(void)
{
    printit(square);
    return 0;
}

Это компилирует и работает без ошибок или предупреждений (gcc - Стена на Linux / x86). Вывод в моей системе:

Call function with parameters 2,4,8.
Result: 4

Таким образом, по-видимому, лишние аргументы просто тихо отбрасываются.

Теперь я хотел бы понять то, что действительно происходит здесь.

  1. Относительно законности: Если я понимаю ответ на Кастинг указателя функции к другому типу правильно, это - просто неопределенное поведение. Таким образом, то, что это выполняет и приводит к разумному результату, является просто чистой удачей, корректной? (или правильность со стороны разработчиков компилятора)
  2. Почему gcc не предупредит меня об этом, даже со Стеной? Это - что-то, что компилятор просто не может обнаружить? Почему?

Я происхожу из Java, где typechecking намного более строг, таким образом, это поведение смутило меня немного. Возможно, я страдаю от культурного шока :-).

10
задан Community 23 May 2017 в 12:19
поделиться