Reputation: 1485
I have 3 functions in my code:
#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()
In another function in this file I need to calculate the size of func_A
and 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
// ...
}
I get the next compilation 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
NOTE: I can solve the error by casting the function pointers, e.g.:
int funcs_size = (void*)func_C - (void*)func_A;
But the same size calculation works perfect for another functions (with also different types)..
Do you know when it is Ok to use functions pointer for such calculations and why in this specific example I get the compilation error?
Thank you for your help
Upvotes: 2
Views: 278
Reputation: 181714
I need to calculate the size of func_A and func_B:
[...]
// End address of B (== start of C) - Start address of A: int funcs_size = func_C - func_A; // Here the error
C does not have any concept of the size of a function, nor any standard way to compute anything related to such a statistic.
I get the next compilation 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
Well that's one thing wrong with your code, sort of. I'd consider it more of a red herring, though. Pointer arithmetic for object pointers is defined in terms of the size of the pointed-to type, so it is not defined for pointers to incompatible types. The type of a function pointer incorporates its return type and, if specified, the types of its parameters, so even if we imagine that your function pointers were object pointers, their types are not compatible, so the subtraction operation would not be permitted.
NOTE: I can solve the error by casting the function pointers, e.g.:
int funcs_size = (void*)func_C - (void*)func_A;
That relies on three separate extensions implemented by your compiler:
void *
, andNone of those have defined behavior as far as the standard is concerned.
But the same size calculation works perfect for another functions (with also different types)
Since we're dealing with language extensions, it's difficult to say what your compiler might or might not accept. I note, however, that different parameter types are not the same thing as incompatible parameter types, and likewise different function types are not necessarily incompatible. I speculate, therefore, that your compiler might accept the difference operation for pointers to compatible function types (as an extension).
Do you know when it is Ok to use functions pointer for such calculations
It depends on what you mean by "OK". If you are trying to write code that conforms to the language standard, then it is never ok. You may not compute a difference between function pointers. You may not convert function pointers to object pointers so as to compute a difference between those.
You may convert function pointers to integers and compute their difference, but the conversion results are implementation-defined, and it is not guaranteed that there is any integer type that can represent converted function pointers without data loss.
In any event, whether a pointer difference or an integer difference is computed, the meaning of that difference is completely unspecified. Even if we assume that we thereby compute the difference between the start address of one function and that of the other, relative to some common, linear address space, there are no guarantees whatever about how the functions are arranged in memory -- not about their relative order, not about their contiguity, not about padding or alignment, nothing.
Upvotes: 2
Reputation: 825
I need to calculate the size of
func_A
andfunc_B
You may want to reassess that need, or edit your question to provide some justification here if you want more-useful answers.
Do you know when it is Ok to use functions pointer for such calculations
In the absence of any indication of what platform you're using we must assume you're talking about the C Abstract Machine, and in that case it is never OK.
and why in this specific example I get the compilation error?
Because the compiler is in this instance following the standard and also helpfully informing you of that.
Upvotes: 0