Force GCC not to optimize away an unused variable?

安稳与你 提交于 2020-01-03 14:16:58

问题


One of the namespaces in my program is spread between two files. One provides the "engine", the other uses the "engine" to perform various commands. All of the initializations are performed on the "engine" side, including caching parameters fetched from setup library.

So, there's engine.cpp with:

    #include <stdio.h>
    #include "ns.h"

    namespace MyNS
    {

        unsigned char variable = 0;

        void init()
        {
            variable = 5;
            printf("Init: var = %d\n",variable);
        }

        void handler()
        {
            // printf("Handler: var = %d\n",variable);
        }
    }

The variable happens never to be used again in engine.cpp but it's extensively used in commands.cpp.

    #include <stdio.h>
    #include "ns.h"

    namespace MyNS
    {
       extern unsigned char variable;

      void command()
       {
          printf("Command: var = %d\n",variable);
       }
    }

After compiling and linking, I'm getting:

Init: var = 5
Command: var = 1

Now, if I uncomment the printf() in handler() I'm getting:

Engine: var = 5
Command: var = 5
Handler: var = 5

What would be the "correct" way to force GCC not to optimize it away in such a way that accessing it through extern from the other file would fetch the right value? Preferably without reducing the -O level for the rest of the application?

(for completeness case, main.h and ns.h: )

    #include "ns.h"

    int main(int argc, char** argv)
    {
        MyNS::init();
        MyNS::command();
        MyNS::handler();

        return 0;
    }

    namespace MyNS
    {
        void init();
        void command();
        void handler();
    }

This minimized testcase doesn't exhibit this particular behavior; it seems one needs this situation to occur in much more complex environment to happen...


回答1:


eh... the solution was quite trivial.

I exchanged places of the declaration and definition of the variable.

engine.cpp:

extern unsigned char variable;

command.cpp:

unsigned char variable = 0;

That way the compiler has no doubts about need for this variable's existence while compiling commands and in engine it has to reach to the existing instance, it can't just create a temporary one on the spot.


EDIT: Now I've discovered another peculiarity. The value changes depending on where it's written to. The section of code in question is:

1:   varso = SharedObject::Instance()->varso;
2:  memset(det_map,0,sizeof(det_map));
3:  memset(gr_map,0xFF,sizeof(gr_map));
4:  memset(gr_ped,false,sizeof(gr_ped));
5:  memset(&stan,0,sizeof(stan));

6:  stan.SOTUstage = 1;
7:  PR_SOTU = varso->NrPSOTU;

The variable occurs near a place where several arrays are initialized with memset. The variable in question is PR_SOTU (the uppercase is inherited from when it was still a macro, and since it acts along with several other macros acting in a very similar context, it's likely to stay that way).

If move the assignment from its line 7 and place it after lines 1, 2 or 3, it receives the correct value 5. Placed after line 4 it gets the value 18. Anything below, and the value is 1. I moved definition of the variable to a different place (it was the last on the list of all namespace-globals, now it's first) to exclude possibility something writes at that specific memory location, but the behavior remains.



来源:https://stackoverflow.com/questions/26608731/force-gcc-not-to-optimize-away-an-unused-variable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!