【发布时间】:2018-10-21 20:17:27
【问题描述】:
是否有(自动)解决方案来减少使用模板编译的 C++ 代码大小? 现在,由于模板和命名空间,符号被破坏并且非常大。
我知道每个函数后面都有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* 下一个指针大小 + 头指针,可能是内存中 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 字节的二进制大小。
【问题讨论】:
-
好吧,在 posix 上,总是有
strip命令。您是否使用-g调试选项进行编译?一般来说,类型和变量的名称不应该出现在编译代码中。
标签: c++ templates gcc embedded