[C++] 头文件中慎用局部静态变量

By | 2015-05-01

先看看例子吧:

// SomeClass.h
class SomeClass {
public:
    static string &func1(void) {
        static string s1;
        return s1;
    }
    static string &func2(void);
};
// SomeClass.cpp
string &SomeClass::func2(void) {
    static string s2;
    return s2;
}

看出区别了吗? 正常情况下是不会有什么问题的, 但如果:

  1. SomeClass 在 A.so 中
  2. 又有个 B.so 加载了 A.so
  3. A.so 和 B.so 都通过 func1 来更改 s1 的值

就会造成:

s1 被创建两次, 并且在 A.so 和 B.so 中有单独的值, 互相独立

而相对的, func2 并不会出现该问题

目测原因是写在头文件中的静态方法被每个编译模块单独编译进模块内了, 是否编译器相关未知

目前采用以下方法绕道解决:

// SomeClass.h
extern string &GetStringRef(const char *token);
class SomeClass {
public:
    static string &func1(void) {
        static string &s1 = GetStringRef("SomeClass");
        return s1;
    }
    static string &func2(void);
};
// SomeClass.cpp
string &GetStringRef(const char *token) {
    static map m;
    return m[token];
}
string &SomeClass::func2(void) {
    static string s2;
    return s2;
}

JJYY:

  • 在 Android JNI 中遇到该问题
  • 会有该诡异需求是因为使用宏自动生成函数, 例如类名注册等等, func1 必须在头文件中申明并实现

转载请注明来自: http://zsaber.com/blog/p/18

既然都来了, 有啥想法顺便留个言呗? (无奈小广告太多, 需审核, 见谅)

Category: C++

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注