приведение функции приводит к команде прерывания gcc

в следующем коде в файле func.c:

#include <stdio.h>

int Myfunc1(int i, int z)
{
    return i;
}

int main()
{
    int ans;

    /*  casting the function into an 'int (int)' function   */
    ans = ((int(*)(int))(Myfunc1))(5);

    printf("ans: %d\n\n", ans);

    return 0;
}

я попытался преобразовать функцию int (int, int) в функцию int (int) и получил предупреждение gcc и примечание:

func.c:13:32: warning: function called through a non-compatible type [enabled by default]
func.c:13:32: note: if this code is reached, the program will abort

и при попытке запустить я получаю:

Illegal instruction (core dumped)

но если я скомпилирую этот файл с расширением .cpp, заканчивающимся компилятором gcc, он будет работать нормально. кто-нибудь может объяснить проблему компилятора в случае .c?


person user3115031    schedule 18.12.2013    source источник
comment
Я попытался преобразовать функцию int(int, int) в функцию int(int). Почему? Вы определенно не должны этого делать. Как в C, так и в C++ не определен вызов функции через указатель на несовместимый тип.   -  person    schedule 18.12.2013


Ответы (2)


GNU GCC распознает все следующие файлы как файлы C++ и будет использовать компиляцию C++ независимо от того, вызываете ли вы ее через gcc или g++: .C, .cc, .cpp, .CPP, .c++, .cp или .cxx.

Из https://stackoverflow.com/a/1546107/1767861

В этом случае gcc компилирует его в C++, который, кажется, принимает приведение. Это почему ? См. https://stackoverflow.com/a/559671/1767861.

person Thomas Ruiz    schedule 18.12.2013

Проблема в том, что ваша подпись для Myfunc1 и указатель на функцию, к которому вы пытаетесь привести, имеют несовместимые типы. Вместо этого вам нужно сделать следующее:

ans = ((int(*)(int, int))(Myfunc1))(5, 5);

ссылка, опубликованная Томасом Руисом, объясняет, почему она не определена поведение.


В итоге:

Приложение J.2

Поведение не определено в следующих обстоятельствах:

-- Указатель используется для вызова функции, тип которой несовместим с типом, на который указывает указатель (6.3.2.3).

6.3.2.3/8

Указатель на функцию одного типа может быть преобразован в указатель на функцию другого типа и обратно; результат сравнивается с исходным указателем. Если преобразованный указатель используется для вызова функции, тип которой несовместим с типом, на который указывает указатель, поведение не определено.

person Community    schedule 18.12.2013