我程序中的一个命名空间分布在两个文件中。一个提供"引擎",另一个使用"引擎"执行各种命令。所有初始化都在"引擎"上执行。方面,包括从安装库中获取的缓存参数。
所以,那里有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.h
和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();
}
这种最小化的测试用例并没有表现出这种特殊的行为;似乎人们需要在更复杂的环境中发生这种情况......
答案 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
。我将变量的定义移到了另一个地方(它是所有命名空间全局列表中的最后一个,现在它是第一个),以排除在特定内存位置写入的可能性,但行为仍然存在。