Я разрабатываю встроенное приложение для Cortex M3 с GCC 4.8 из инструментария GNU ARM в C ++. Приложение использует некоторые синглтоны, которые создаются с помощью локальной статической переменной функции, например (реальный код):
GlobalDataTypeRegistry& GlobalDataTypeRegistry::instance()
{
static GlobalDataTypeRegistry inst;
return inst;
}
Что является классическим подходом для реализации синглетонов в C ++. Проблема в том, что размер выходного кода увеличивается, когда я использую такое создание экземпляров, что, очевидно, означает, что компилятор / компоновщик добавляет некоторый служебный код для правильной инициализации / уничтожения объекта-одиночки.
Вот минимальный пример, который позволяет воспроизвести проблему:
Это скомпилируется в 66k кода (-Os):
struct A
{
A() { __asm volatile ("nop"); }
~A() { __asm volatile ("nop"); }
};
A& getA()
{
static A a;
return a;
}
int main()
{
(void)getA();
return 0;
}
Это скомпилируется в 9k кода (-Os):
struct A
{
A() { __asm volatile ("nop"); }
~A() { __asm volatile ("nop"); }
};
static A a; // Extracted from the function scope
A& getA()
{
return a;
}
int main()
{
(void)getA();
return 0;
}
Если линия (void)getA();
полностью закомментирован, окончательный размер двоичного файла будет примерно 4k.
Вопрос заключается в следующем: какие варианты мне нужны, чтобы избежать лишних 62 Кб кода для этого синглтона, кроме извлечения статической переменной из области действия функции? Есть ли какие-либо варианты, чтобы сообщить GCC, что нет необходимости вызывать деструктор синглтона при выходе из приложения (так как он никогда не завершается)? Есть ли другие способы оптимизации?
добавлять -fno-threadsafe-statics
возможность g++
команда, и ваш размер кода будет уменьшен.
Вот мой пример кода:
class X {
private:
X() { };
public:
~X() { };
static X* get_instance() {
static X instance;
return &instance;
}
void show() {
asm("");
}
};int main() {
X* temp = X::get_instance();
temp->show();
while (true) {
asm("");
}
}
Рекомендации:
Вы можете создать свой синглтон с новым размещением в буфере, реализованном с станд :: aligned_storage.