Home > Net >  For a function that takes a const struct, does the compiler not optimize the function body?
For a function that takes a const struct, does the compiler not optimize the function body?

Time:08-30

I have the following piece of code:

#include <stdio.h>

typedef struct {
    bool some_var;
} model_t;

const model_t model = {
    true
};

void bla(const model_t *m) {
    if (m->some_var) {
        printf("Some var is true!\n");
    }
    else {
        printf("Some var is false!\n");
    }
}

int main() {
    bla(&model);
}

I'd imagine that the compiler has all the information required to eliminate the else clause in the bla() function. The only code path that calls the function comes from main, and it takes in const model_t, so it should be able to figure out that that code path is not being used. However:

Without inline

With GCC 12.2 we see that the second part is linked in.

If I inline the function this goes away though:

With inline

What am I missing here? And is there some way I can make the compiler do some smarter work? This happens in both C and C with -O3 and -Os.

CodePudding user response:

The compiler cannot optimize the else path away as the object file might be linked against any other code. This would be different if the function would be static or you use whole program optimization.

CodePudding user response:

The compiler does eliminate the else path in the inlined function in main. You're confusing the global function that is not called anyway and will be discarded by the linker eventually.

If you use the Enter image description here

Additionally, you use static or inline keywords to achieve something similar.

CodePudding user response:

You can use:

#include <stdlib.h>     // exit
#include <stdio.h>
typedef struct
{
        bool some_var;
}model_t;
const model_t model = { true };
void bla(const model_t*m)
{
        // HANDLE NULL POINTER EXCEPTIONS
        if ( m )
        {
                printf( "bla model_t* pointer is NULL\n");
                exit(1);
        }
        if (m->some_var)
        {
                printf("Some var is true!\n");
        }
        else
        {
                printf("Some var is false!\n");
        }
        // Better to use return. Reason: future enhancement may have changes to return types.
        return;
}

int main()
{
        bla(&model);
        return 0;
}
/*
$ # Using zero optimization
$ gcc -Wall -O0 73526838.cpp -o ./a.out
Optimization    Size of a.out
-O0             68162
-O1             68162
-O2             68242
-O3             68242   I used to use this optimization without using -g option.
...
*/

Using -O3, without using the -g option used to help:

  1. security
  2. log files based on log level/error/exception based on a server/client parameter.
  3. input file/output from the client/server
  4. size of the binary
  5. use dependence libraries instead of using static library based on dll/.sl/.so library provider's business. This will reduce the size of the binary and the binary to call dependent library function (optimization) only when required.
  •  Tags:  
  • c c
  • Related