强制GCC不要优化掉未使用的变量?

时间:2014-10-28 12:45:32

标签: c++ gcc compiler-optimization

我程序中的一个命名空间分布在两个文件中。一个提供"引擎",另一个使用"引擎"执行各种命令。所有初始化都在"引擎"上执行。方面,包括从安装库中获取的缓存参数。

所以,那里有engine.cpp

    #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);
        }
    }

该变量永远不会在engine.cpp中再次使用,但在commands.cpp中广泛使用。

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

    namespace MyNS
    {
       extern unsigned char variable;

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

编译和链接后,我得到了:

  

初始值:var = 5
  命令:var = 1

现在,如果我取消注释handler()中的printf(),我会得到:

  

发动机:var = 5
  命令:var = 5
  处理程序:var = 5

&#34;正确的&#34;迫使GCC不以这样的方式优化它,以便通过extern从另一个文件访问它将获取正确的值?最好不降低申请其余部分的-O水平?

(完整性情况,main.hns.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();
    }

这种最小化的测试用例并没有表现出这种特殊的行为;似乎人们需要在更复杂的环境中发生这种情况......

1 个答案:

答案 0 :(得分:1)

呃......解决方案非常简单。

我交换了变量的声明和定义的地方。

engine.cpp

extern unsigned char variable;

command.cpp

unsigned char variable = 0;

这样编译器毫无疑问在编译commands时需要存在此变量,而在engine中它必须到达现有实例,它不能只是当场创造一个临时的。


编辑:现在我发现了另一个特点。值会根据其写入的位置而变化。有问题的代码部分是:

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;

变量出现在使用memset初始化多个数组的位置附近。有问题的变量是PR_SOTU(大写字母是从它仍然是一个宏时继承而来的,并且因为它与在非常相似的上下文中运行的其他几个宏一起行动,它可能会保持这种状态)

如果从第7行移动分配并将其放在第1,2或3行之后,它将收到正确的值5。放在第4行后,它获得值18。以下任何内容,值为1。我将变量的定义移到了另一个地方(它是所有命名空间全局列表中的最后一个,现在它是第一个),以排除在特定内存位置写入的可能性,但行为仍然存在。