【发布时间】:2014-12-23 21:08:56
【问题描述】:
我的程序中的一个命名空间分布在两个文件之间。一个提供“引擎”,另一个使用“引擎”执行各种命令。所有初始化都在“引擎”端执行,包括从设置库中获取的缓存参数。
所以,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
什么是“正确”的方法来强制 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();
}
这个最小化的测试用例没有表现出这种特殊的行为;似乎需要在更复杂的环境中发生这种情况......
【问题讨论】:
-
我很难相信对具有外部链接的变量的赋值会被优化掉。你确定不是对
init的调用被优化掉了吗? -
我觉得这可能是静态初始化顺序问题?
-
也许你想要
volatile.... -
我不能用一个小例子来重现这个 - 编译器不应该像你声称的那样优化它。你能创建一个 complete 可编译的例子来展示这个吗?另外,您使用的是什么平台和 gcc 版本,使用了任何特定的编译器标志?任何其他不寻常的事情,例如多线程,动态加载的共享库,您的 command_x()/init() 函数实际上是从全局对象的构造函数等调用的吗?
-
另外,我将尝试编写一个最小化的测试用例。以目前的形式,该程序太大而不能仅仅“裁剪一些行”。
标签: c++ gcc compiler-optimization