我已启用编译器和链接器优化,以期从我的ARM32可执行文件中删除所有未使用的代码/数据。从我的映射文件中,我可以看到未使用的代码部分确实已被丢弃,因此优化标志几乎可以正常工作,除了未使用类的静态成员函数/变量。我们将不胜感激关于如何摆脱这一点的任何想法,因为这在资源受限的嵌入式平台上加起来相当多!
这里是使用g ++ 7.5编译的MVCE。在Ubuntu 18.04上
#include <string>
#include <iostream>
#include <string.h>
class unusedClass {
public:
unusedClass() {};
~unusedClass() {};
static std::string className;
void initArray(void) {
memset(a, 0, sizeof(a));
}
void printArray(void) {
for (auto& i:a) {
std::cout<< i << std::endl;
}
}
static void printClassName(void) {
std::cout << "This is a static member function of the class \"UNUSED CLASS\""<< std::endl;
}
private:
int a[1000];
};
std::string unusedClass::className = "unusedClass";
int main() {
std::cout << "Running the Clean-up Dead Code Test" << std::endl;
return 0;
}
使用优化标志编译以删除未使用的代码
g++ -Os -flto test.cpp
检查静态成员变量是否已编译到可执行文件中
readelf -a --wide a.out | awk '$4 == "OBJECT" { print }'
29: 0000000000201140 32 OBJECT LOCAL DEFAULT 24 _ZN11unusedClass9classNameB5cxx11E
作为StoryTeller的指针,_ZN11unusedClass9classNameB5cxx11E
不是成员函数,而是成员变量static std::string className
。
如果不希望将函数和变量编译为可执行文件,则使用constexpr instead of static
通常会导致此结果。在您的示例中,类名在编译时是已知的,因此无论如何,使用constexpr
将是更惯用的解决方案。
这是一个工作示例,其中的变量未编译:https://godbolt.org/z/bqsuTA
注意:您只能在constexpr上下文中使用const char *
,不能在std::string
中使用。