Home > front end >  gcc optimization flag: it "fixes" the code
gcc optimization flag: it "fixes" the code

Time:10-02

Basically, I have a piece of code that converts a function pointer to an object pointer type. During compilation I see this warning

ISO C forbids conversion of function pointer to object pointer type

The code works without any problem if the optimization flag is active, for example

gcc -O1

As soon as I remove all the optimizations the code breaks, for example

gcc -O0 -ggdb

After months of research I found the problem that breaks my code but I don't understand why the release build (optimization active) works.

Basically what I have in the code is an array where each object in the array is a function pointer. The functions are defined with a macro and have a void return type. In order to access to the function through the array I need to cast the function definition with (void *) and this is where the compiler complains about.

Is the optimization flag that does the magic under the hood?

EDIT: Added code example

Here is a code example:

static const struct
{
    UINT8       parameter1;
    UINT8       parameter2;
    UINT8       parameter3;
    void *      function1;
    void *      function2;
} handlerList[] =
{
    { 8, 12, 0, (void *)FUNC1, (void *)FUNC2 },
    { 12, 24, 1, (void *)FUNC3, (void *)FUNC4 },
    { 3, 12, 2, (void *)FUNC5, (void *)FUNC6 },
};

FUNC1, FUNC2... are macros that define all the functions with void return type.

When I have to pass (returning it) the function pointer to other code I use this snippet:

return handlerList[i].function1

In which way I can define an array of function pointer and recall it without convert function pointer to object pointer?

CodePudding user response:

You didn't show your code but i'll try to guess. Suppose you have:

int main(void)
{
    int *p = main; // This is UB!
    *p = *p;

    return 0;
}

p is an object type pointer but it holds function pointer value. On many architectures code and data are in the same address space but pages with code sections are read-only. With -O1 compiler just eliminates *p=*p as useless operation and nothing happen. With -O0 compiler generates code which attempts to write to read-only page.

CodePudding user response:

The reason the C Standard does not define conversions between function and data pointers is they may have different representations, including a different size. Most compilers will generate correct code if code and data pointers happen to have the same size on the target architecture, yet the warning is important and you should define function1 and function2 as function pointers with an appropriate prototype.

In your case, this is not the likely explanation for your observations, but it is unclear what happens when you write { 8, 12, 0, (void *)FUNC1, (void *)FUNC2 }, because FUNC1 and FUNC2, as macros, are probably not function expressions at all.

  • Related