Статическая константная инициализация iPhone / Release - PullRequest
2 голосов
/ 11 июля 2010

У меня есть кроссплатформенная библиотека, которая имеет странную проблему только на 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, которые даже не выполняются.Просто уменьшив размер кода, я могу решить эту проблему, но для меня это не вариант.Кроме того, приложение не такое большое, память не может быть проблемой.

Кстати, cColor включен в предварительно скомпилированный заголовок в библиотеке и позже в приложении, которое использует библиотеку.

Помогите!У меня действительно нет идей.


Отредактировано: вот больше информации ...

Я перенес только код инициализации из библиотеки в свое приложение, и теперь константы получаютинициализирован правильно.

Я действительно думаю, что компоновщик что-то напутал.

Есть идеи?

Ответы [ 3 ]

1 голос
/ 11 июля 2010

Вы можете легко предотвратить фиаско статического порядка инициализации: 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 голосов
/ 12 июля 2010

Это общий случай со статическими начальными значениями внутри библиотеки.Код со статической инициализацией должен быть связан с основным приложением.Библиотека - это просто набор файлов .o, и во время компоновки компоновщик выбирает, какие файлы .o он хочет включить в конечный исполняемый файл.Если ваше основное приложение не ссылается на эти переменные, компоновщик определяет, что объектный код не используется, и поэтому .o не извлекается, и, следовательно, инициализаторы не инициализируются.Быстрый тест состоит в том, чтобы ссылаться на них в основных источниках exe (не в вашей библиотеке) или попробовать флаг -Wl,-whole-archive или -force_load для gcc, чтобы принудительно включить все объекты .o из вашей библиотеки.

0 голосов
/ 12 июля 2010

Я убежден, что это ошибка компоновщика.Я только что нашел работу, которая действительно глупа.Я переместил одну встроенную функцию из класса cColor в cColor.cpp.У меня больше ничего не было в cColor.cpp, кроме статической инициализации const.

Я предполагаю, что, поскольку в некоторых случаях в блоке перевода ничего нет, компоновщик решает игнорировать его.

IЯ мог бы послать это в Apple, чтобы узнать, что они думают об этом.

PS Просто чтобы прояснить, я сначала подумал, что это повреждение памяти, но у меня нет статических выделений памяти в моей библиотеке / приложении.Также я протестировал код с несколькими менеджерами памяти с различными функциями отладки, и код даже не содержит утечек.

...