g++: использование синглтона во встроенном приложении

Я разрабатываю встроенное приложение для 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, что нет необходимости вызывать деструктор синглтона при выходе из приложения (так как он никогда не завершается)? Есть ли другие способы оптимизации?

2 ответа

Решение

Добавлять -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("");
    }
}

Рекомендации:

Вы можете создать свой синглтон с новым размещением в буфере, реализованном с помощью std::align_storage.

Другие вопросы по тегам