Ошибка - <объявления функций> не являются указателями на совместимые типы - PullRequest
2 голосов
/ 26 марта 2019

В моем коде 3 функции:

#pragma Code(".my_functions")
    int  func_A(volatile ulong *from, volatile ulong *to, ulong size) {...}
    int  func_B(uint32_t *buf_src, int size) {...}
    void func_C(int size, uint32_t *buf) {...}
#pragma Code()

В другой функции в этом файле мне нужно вычислить размер func_A и func_B:

int calc_size()
{
        // End address of B (== start of C) - Start address of A:
        int funcs_size = func_C - func_A; // Here the error

        // ...
}

Я получаю следующую ошибку компиляции:

error: 'void (*)(int, uint32_t *)' (aka 'void (*)(int, unsigned int *)') and 'int (*)(volatile ulong *, volatile ulong *, ulong)' (aka 'int (*)(volatile unsigned long *, volatile unsigned long *, unsigned long)') are not pointers to compatible types

ПРИМЕЧАНИЕ: Я могу устранить ошибку, приведя указатели функций, например ::

int funcs_size = (void*)func_C - (void*)func_A; 

Но тот же расчет размера идеально подходит для других функций (также с разными типами) ..

Знаете ли вы, когда можно использовать указатель функции для таких вычислений и почему в этом конкретном примере я получаю ошибку компиляции?

Спасибо за вашу помощь

Ответы [ 2 ]

2 голосов
/ 26 марта 2019

Мне нужно вычислить размер func_A и func_B:

[...]

        // End address of B (== start of C) - Start address of A:
        int funcs_size = func_C - func_A; // Here the error

C не имеет никакого понятия о размерефункция, ни какой-либо стандартный способ вычисления чего-либо, связанного с такой статистикой.

Я получаю следующую ошибку компиляции:

error: 'void (*)(int, uint32_t *)' (aka 'void (*)(int, unsigned int *)') and 'int (*)(volatile ulong *, volatile ulong *, ulong)' (aka 'int (*)(volatile unsigned long *, volatile unsigned long *, unsigned long)') are not pointers to compatible types

Ну, это одна вещь не так с вашим кодом, вроде.Я бы посчитал это скорее красной селедкой.Арифметика указателей для объектных указателей определяется в терминах размера указательного типа, поэтому она не определяется для указателей на несовместимые типы.Тип указателя на функцию включает в себя тип возвращаемого значения и, если он указан, типы его параметров, поэтому даже если мы представим, что указатели на функции были указателями на объекты, их типы несовместимы, поэтому операция вычитания не будет разрешена.

ПРИМЕЧАНИЕ : Я могу устранить ошибку, приведя указатели функций, например:

int funcs_size = (void*)func_C - (void*)func_A; 

Это зависит от трех отдельных расширений, реализованных вашимкомпилятор:

  • , преобразующий указатель функции в указатель объекта,
  • , вычисляющий разницу между указателями типа void *, и
  • , вычисляющий разницу между указателями наобъекты, которые не являются двумя членами одного и того же массива или в позиции, расположенной сразу после конца массива.

Ни один из них не определил поведение в отношении стандарта.

Но тот же расчет размера идеально подходит для других функций (также с разными типами)

Так как мыИмея дело с языковыми расширениями, трудно сказать, что может или не может принять ваш компилятор.Однако я отмечаю, что различные типы параметров - это не то же самое, что несовместимые типы параметров, и также разные типы функций не обязательно несовместимы.Поэтому я предполагаю, что ваш компилятор может принять разностную операцию для указателей на совместимые типы функций (как расширение).

Знаете ли вы, когда можно использовать указатель функции для таких вычислений

Это зависит от того, что вы подразумеваете под «ОК».Если вы пытаетесь написать код, который соответствует языковому стандарту, тогда никогда нормально.Вы не можете вычислить разницу между указателями на функции.Вы не можете преобразовывать указатели функций в указатели объектов, чтобы вычислять разницу между ними.

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

В любом случае, если вычисляется разность указателей или целочисленная разница, значение этой разницы полностьюнеопределенные.Даже если мы предположим , что таким образом вычислим разницу между начальным адресом одной функции и адреса другой, относительно некоторого общего линейного адресного пространства, нет никаких гарантий относительно того, как функции расположены впамять - не об их относительном порядке, не об их смежности, не об заполнении или выравнивании, ничего.

0 голосов
/ 26 марта 2019

Мне нужно рассчитать размер func_A и func_B

Возможно, вы захотите переоценить эту потребность или отредактируйте свой вопрос, чтобы предоставить какое-то обоснование здесь, если вы хотите больше-полезные ответы.

Знаете ли вы, когда можно использовать указатель функций для таких вычислений

В отсутствие каких-либо указаний о том, какую платформу вы используете, мыдолжен предположить, что вы говорите об абстрактной машине C, и в этом случае это никогда не будет нормально .

, и почему в этом конкретном примере я получаю ошибку компиляции?

Поскольку компилятор в этом случае следует стандарту, а также предупреждает вас об этом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...