【发布时间】:2011-09-08 12:50:25
【问题描述】:
我想编写一些依赖于静态变量值的代码。所以我想添加一些检查以消除从其他静态变量构造函数调用此代码的可能性。并防止静态初始化命令一劳永逸。例如:
static Foo foo = Foo();
// this function should be called ONLY from main program conrol flow
// ONLY after all static variable initialization was complete! ONLY!
int bar()
{
#ifdef _DEBUG
if(! CRT_was_initialized_and_main_function_was_called ) ShowErrorMessage();
#endif
if(foo.somefunction() == 2) return 0; else return -1;
}
//here inattentive programmer will caught error message during debug
const int barConstant = bar();
int main()
{
//now all is fine
const int barConstant = bar();
}
我该怎么做?如何检查我的函数是否在 main 函数之后被调用?
更新:Foo 对象的初始化代码非常繁重,可能会很慢甚至抛出异常
UPDATE2:这样做没有生命危险。大多数情况下,bar 功能之前的注释都可以正常工作。我对某种调试检查感兴趣,以惩罚程序调试版本中粗心的程序员,而不是手动执行此操作。而且它可能是非标准方式,例如调用一些仅适用于 MSVC 的疯狂内置函数。
【问题讨论】:
-
如果你不想在程序每次执行时都验证,你可以设置一个断点,进入Debug,看看是否初始化完成。
-
在您的代码中,第一行是声明一个函数,而不是一个类实例。
-
我的印象是当前的范式是“静态且全局状态不好”。以与此类似的问题为主要原因。有重构的机会吗?
-
这个 Foo 对象实际上非常重,它的初始化需要很长时间,并且可能导致在 CRT 初始化期间不应该抛出的错误。相比之下, bar 函数应该很轻,并且在循环等代码的非常热的部分中调用。我在这里看到的唯一可能的重构是使 Foo 成为像对象一样的单例......但这将是唯一解决方案的交易。
-
你能给
main加好友吗? ideone 和 cormeau 让我可以,但我无法访问实际的编译器/链接器,因此我可以检查它在单独的翻译单元中的行为方式。您仍然有输入main后可能会发生静态初始化的问题,但至少您会知道只有main可以创建您的Foo对象。