Сократить двоичный размер, переименовав символы в C ++ - PullRequest
0 голосов
/ 21 октября 2018

Существует ли (автоматическое) решение для уменьшения размера кода C ++, скомпилированного с -O, использующего шаблоны?Прямо сейчас символы искажены и довольно велики из-за шаблонов и пространств имен.

Мне известно о asm("symbolName") после каждой функции, но много писать, когда у вас много символов.

Я ищу больше своего рода автоматизированный инструмент, который удалит и переименует все символы (или заменит их на простое числовое значение?)

Если вопрос не ясен, вотпример 2 кодов (один ориентированный на C, другой ориентированный на C ++):

// C like, using virtual table + next pointer
struct Test
{
    virtual bool run() = 0;
    Test * next;
    Test() : next(nullptr) {}
    virtual ~Test() { delete next; }
};

Test & head = [...];
bool runTests() 
{ 
    Test * t = &head; 
    while (t) { if (!t->run()) return false; t = t->next; }
    return true;
}

Для 10 тестов в 32-битных системах требуется: 10 * размер виртуальной таблицы + 10 * следующий размер указателя + headуказатель, вероятно, размер 30 указателей в памяти, но размер кода (.text) минимален.В моей системе после запуска strip -Alx a.out я получаю двоичный размер 9336 байт

против:

template <typename Child, typename Next>
struct Test : public Child, public Next
{
    bool run() 
    { 
        if (!static_cast<Child*>(this)->run()) return false; 
        return Next::run(); 
    }
};

struct End
{
   static bool run() { return true; }
};

// Example follower
volatile bool g = true;
// Example follower
struct Test9 { bool run() { return g; } };
struct Test8 { bool run() { return g; } };
struct Test7 { bool run() { return g; } };
struct Test6 { bool run() { return g; } };
struct Test5 { bool run() { return g; } };
struct Test4 { bool run() { return g; } };
struct Test3 { bool run() { return g; } };
struct Test2 { bool run() { return g; } };
struct Test1 { bool run() { return g; } };

Test<Test1, Test<Test2, Test<Test3, Test<Test4, Test<Test5, Test<Test6, Test<Test7, Test<Test8, Test<Test9, End>>>>>>>>> head;
bool runTests() { return head.run(); }

Общий код:

int main()
{
    printf("%s: %s\n", typeid(head).name(), runTests() ? "passed" : "failed");
    return 0;
}

Как правило, это не следуетне имеет никаких указателей, и является минималистским.Однако рекурсивный код шаблона создает очень большие символы, которые занимают место во флэш-памяти (эти символы не удаляются из двоичного файла, поскольку они должны быть идентифицированы).В моем случае последний создает двоичный размер, который имеет 9804 байта.

1 Ответ

0 голосов
/ 22 октября 2018

C ++ - это скомпилированный язык - длина символа никак не влияет на размер кода.Они сохраняются в объектном коде и библиотеках в целях разрешения ссылок и для отладки, но не занимают места в двоичном файле во время выполнения.

Я ищу больше своего рода автоматизированный инструментэто уберет и переименует все символы (или заменит их на простое числовое значение?)

Это именно то, что делает компоновщик;он заменяет символы на адреса.Символы, сохраняемые для отладки, могут быть удалены с помощью опции компоновщика или отдельной утилиты strip.

Если ваша цель - не размещенная среда с открытым исходным кодом, бинарный файл, загруженный на цель, обычно не включаеттаблица символов отладки в любом случае;так что в этом случае разбор не имеет никакой другой цели, кроме как предотвратить использование символического отладчика.Для отладки символы загружаются в отладчик, работающий только на хосте разработки, и отсутствуют в целевом объекте.

Если ваш код раздулся из-за использования шаблонов, это никак не связано с длинойимена символов.Каждый раз, когда создается экземпляр шаблона с различными параметрами шаблона, будет создаваться новый код, поэтому очень легко получить большой объем кода, если вы создаете много разных версий одного шаблона.

...