【问题标题】:Block function/fail if function called during static global initialization如果在静态全局初始化期间调用函数,则阻止函数/失败
【发布时间】:2012-03-13 18:11:36
【问题描述】:

如果在全局静态变量的初始化期间调用,我是否会导致函数失败?该函数使用另一个全局静态变量(来自不同的单元),因此在启动期间调用是不安全的。

我有两个原因。首先,如果我能以某种方式检测到这种情况,我可以打印一个有用的调试消息,而不是从它那里得到一个段错误和古怪的堆栈跟踪,否则会失败。其次,我可以防止它意外工作。有时库和目标文件正好对齐,依赖顺序也很好,因此您认为代码是正确的,但事实并非如此。

注意:这不是一个单独的程序,而是一个库函数,因此将一些全局变量标记为 main 的第一步可能不是一个可行的选择。更糟糕的是,在一种情况下,它实际上是一个模板函数,其中引用了一个 extern static。

注意:出于效率的原因,我希望避免将静态封装在函数调用中的明显解决方案。

GCC 欺骗是允许的,因为在我们的一个平台上检测到这一点就足够了。

【问题讨论】:

    标签: c++ gcc


    【解决方案1】:

    也许是这样的:

    #include <iostream>
    
    bool& init()
    {
        static bool inited=false;
        return inited;
    }
    
    class A
    {
    public:
    
        A()
        {
            if (! init())
            {
                std::cout<<"fail"<<std::endl;
            }
            else
            {
                std::cout<<"ok"<<std::endl;
            }
        }
    
    };
    
    A a1;
    
    int main()
    {
        init() = true;
        A a2;
    }
    

    全局初始化会失败,在 main() 中创建会通过。


    上面看起来不太好,但是没有其他方法,因为(正如您在问题中所说)该标准不保证在进入 main 之前初始化对象的顺序。唯一的建议是在启动main() 之前避免创建对象。

    【讨论】:

    • 我确实相信 main 中的标志会起作用,问题是其中许多函数都在库中,并且很难协调设置各种标志。
    • @edA-qamort-ora-y 除了明显的“不创建全局对象”之外,我没有看到其他方式
    • 确认没有其他方法也可以(我不指望奇迹,只是希望)。
    猜你喜欢
    • 1970-01-01
    • 2021-09-06
    • 1970-01-01
    • 1970-01-01
    • 2016-11-29
    • 1970-01-01
    • 2011-02-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多