2010-07-11 107 views
2

我有一个跨平台库,只有在iPhone上有奇怪的问题,只有在释放。静态const初始化iPhone /发行

// .h 
class cColor 
{ 
public: 
    static const cColor Red; 
    static const cColor Green; 
    static const cColor Blue; 

    u8 r; 
    u8 g; 
    u8 b; 
    u8 a; 

    inline cColor(...) : ... { } 
}; 

// .cpp 
const cColor cColor::Red(0xFF, 0x00, 0x00); 
const cColor cColor::Green(0x00, 0xFF, 0x00); 
const cColor cColor::Blue(0x00, 0x00, 0xFF); 

它看起来像一个初始化顺序失败,但问题不是静态方法,但后来在程序中。所有的cColor :: Red,Green,Blue都被设置为0.实际上,我在构造函数的{}中放置了一些printf,它不打印任何东西,但可能它没有问题,因为它在全局初始化过程中。现在最糟糕的部分是:库在Release中工作,直到最近我添加了几个函数(200-300行),甚至没有被执行的Objective-C代码。只是从代码大小切割我可以解决这个问题,但这不是我真正的选择。此外,应用程序不是那么大,内存不能成为问题。

Btw cColor包含在库中的预编译头文件中,后来在使用该库的应用程序中。

帮助!我真的没有想法。


编辑:下面是详细信息...

我只移动了初始化代码从图书馆到我的应用程序现在 常数得到正确初始化。

我真的认为链接器搞乱了一些东西。

任何想法?

+0

有什么症状? – 2010-07-11 09:14:11

+0

所有静态颜色的rgba值为0.缩进器工作得很好,除了e静态常量。 – Aleks 2010-07-11 18:23:14

+0

通过删除足够多的*任意*代码或删除* Objective-C *代码,您现在可以再次运行它。 – 2010-07-11 22:34:47

回答

0

我确信这是一个链接器错误。我刚刚发现了一件非常愚蠢的工作。我将一个内联函数从cColor类移到了cColor.cpp。除了静态常量初始化之外,我在cColor.cpp中没有其他任何东西。

我的猜测是,因为在某些情况下,链接器决定忽略它,因此在翻译单元中没有其他内容。

我可能会将此发送给苹果,以了解他们对它的看法。

P.S.只是为了清楚我最初的想法是这是内存损坏,但我的库/应用程序中没有任何静态内存分配。此外,我还测试了具有不同调试功能的多内存管理器的代码,代码甚至是免费的。

1

您可以轻松地防止静态初始化顺序的悲剧:http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.15

 
// .h 
class cColor 
{ 
public: 
    static const cColor& Red(); 
    static const cColor& Green(); 
    static const cColor& Blue(); 

    u8 r; 
    u8 g; 
    u8 b; 
    u8 a; 

    inline cColor(...) : ... { } 
}; 

// .cpp 
const cColor& cColor::Red() { 
    static cColor* redColor = new Color(0xFF, 0x00, 0x00); 
    return *redColor; 
}; 

/* etc */ 

我不知道这是否与您的症状有助于虽然。

+0

我不认为我的问题是初始化失败,而不是初始化。我也知道这个解决方案,它会在我的情况下工作,但它比静态常量要慢,因为如果静态变量被初始化,每次调用都会检查它。 – Aleks 2010-07-11 16:13:56

+0

@Alex:你为什么认为每次调用代码时都会检查它?你不认为编译器作者想到这一点,并已经添加了适当的优化! – 2010-07-11 19:47:47

+0

@LumpN:为什么动态创建颜色!只需要一个静态的Color对象。 'static cColor red(0xFF,0x00,0x00);'它将在首次使用时正确创建,而不像您的代码在应用程序关闭时将被正确销毁。 – 2010-07-11 19:49:20

0

这是库中静态inits的常见情况。具有静态初始化的代码必须链接到主应用程序中。一个库仅仅是一个.o文件的集合,并且在链接时,链接器选择它想要包含到最终可执行文件中的哪个.o文件。如果你的主应用程序没有引用这些变量,那么链接器将确定目标代码是未使用的,所以.o不会被拉入,因此初始化程序不会初始化。快速测试是在您的主要exe源文件中引用它们(不在您的库中)或尝试使用-Wl,-whole-archive-force_load标志来gcc强制包含库中的所有.o对象。

+0

变量用于库和可执行文件中。主要的问题是在添加实现的objective-c代码后出现问题。我可以通过删除大约200行的任何目标C代码来修复它。如果会有任何变化,我会对这些标志进行防卫测试。 – Aleks 2010-07-12 00:59:17