Very generally, the C standard basically says that handling an object over a pointer whose type is not aligned with the type of the object itself generates undefined behaviour - There are many exceptions to this general rule, but, apparently, none of them seems to apply to your case.
That means we're moving on very unsafe grounds here, in the first place.
First, you need to distinguish function attributes into two classes:
- Function attributes that actually change something in the behavior or location of the function itself like
aligned
or interrupt
- A function that is not attributed that way will not change its inner code once you declare a pointer to it interrupt
, for example (the code that is generated for the function would need to dynamically change - for example, a "return from interrupt" instruction replaced by a "return normally" one - depending on along what type of pointer it would have been called). This is obviously not possible.
- Function attributes that tell the calling code something about the behaviour that can be expected from the function - like
noreturn
or malloc
, for example. Those attributes sometimes might not modify the function code itself (you'll never know, however...), but rather tell the calling code something about assumptions it can make in order to optimise. These assumptions will affect the calling function only and thus can be triggered by tweaking a pointer (you don't even need a pointer to do that, a modified function prototype should suffice - for the language, that would actually turn out to have the same effect). If you tell the compiler it can make such assumptions and those turn out not to be true, this will, however, lead to all sorts of things go wrong. After all, C makes the programmer responsible for making sure a pointer points to the right type of thing.
There are, however, function attributes that actually restrict the amount of assumptions a calling function would be allowed to make (the most obvious would be malloc
that tells calling code it returns yet untyped and uninitialized memory). Those should be relatively safe to use (I do, however, fail to come up with a use case atm)
Without very detailed knowledge on what belongs into (1) or (2) above, and what exactly a function attribute might affect in both called and calling code (which would be very difficult to achieve, because I don't recall to ever have seen that documented in detail), you thus will not be able to decide whether this pointer tweaking actually is possible and what side effects it might generate.
Also, in my opinion, there is not much of a difference between tweaking a pointer to a function and calling an external function with a (deliberately) wrong prototype. This might give you some insight on what you are actually trying to do...