прехвърлянето на функцията води до команда за прекъсване на 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);

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


В обобщение:

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

Поведението е недефинирано при следните обстоятелства:

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

6.3.2.3/8

Указател към функция от един тип може да бъде преобразуван в указател към функция от друг тип и обратно; резултатът трябва да бъде сравнен с оригиналния указател. Ако преобразуван указател се използва за извикване на функция, чийто тип не е съвместим с посочения тип, поведението е недефинирано.

person Community    schedule 18.12.2013