gpt4 book ai didi

c++11 - 如何避免模板实例化和符号表导致的C++代码膨胀?

转载 作者:行者123 更新时间:2023-12-02 19:40:45 25 4
gpt4 key购买 nike

几年前我开始了一个裸机 (Cortex-M) 项目。在项目设置时,我们决定使用启用了 C++11/C++14 等的 gcc 工具链,甚至使用 C++ 异常和 rtti。

我们目前正在使用gcc 4.9 from launchpad.net/gcc-arm-embedded (目前有一些问题阻止我们更新到更新的 gcc 版本)。

例如,我编写了一个基类和一个派生类,如下所示(另请参阅运行示例 here ):

class OutStream {
public:
explicit OutStream() {}
virtual ~OutStream() {}
OutStream& operator << (const char* s) {
write(s, strlen(s));
return *this;
}
virtual void write(const void* buffer, size_t size) = 0;
};

class FixedMemoryStream: public OutStream {
public:
explicit FixedMemoryStream(void* memBuffer, size_t memBufferSize): memBuffer(memBuffer), memBufferSize(memBufferSize) {}
virtual ~FixedMemoryStream() {}
const void* getBuffer() const { return memBuffer; }
size_t getBufferSize() const { return memBufferSize; }
const char* getText() const { return reinterpret_cast<const char*>(memBuffer); } ///< returns content as zero terminated C-string
size_t getSize() const { return index; } ///< number of bytes really written to the buffer (max = buffersize-1)
bool isOverflow() const { return overflow; }
virtual void write(const void* buffer, size_t size) override { /* ... */ }
private:
void* memBuffer = nullptr; ///< buffer
size_t memBufferSize = 0; ///< buffer size
size_t index = 0; ///< current write index
bool overflow = false; ///< flag if we are overflown
};

这样我类的客户现在就可以使用例如:

char buffer[10];
FixedMemoryStream ms1(buffer, sizeof(buffer));
ms1 << "Hello World";

现在我想让类的使用更加舒适,并引入了以下模板:

template<size_t bufferSize> class FixedMemoryStreamWithBuffer: public FixedMemoryStream {
public:
explicit FixedMemoryStreamWithBuffer(): FixedMemoryStream(buffer, bufferSize) {}
private:
uint8_t buffer[bufferSize];
};

从现在开始,我的客户可以写:

FixedMemoryStreamWithBuffer<10> ms2;
ms2 << "Hello World";

但从现在开始,我观察到可执行二进制文件的大小不断增加。看来 gcc 为 FixedMemoryStreamWithBuffer 的每个不同模板实例添加了符号信息(因为我们出于某种原因使用了 rtti)。

是否有一种方法可以仅删除某些特定类/模板/模板实例化的符号信息?

为此获得一个仅适用于非可移植 gcc 的解决方案是可以的。

出于某种原因,我们决定更喜欢模板而不是预处理器宏,我想避免使用预处理器解决方案。

最佳答案

首先,请记住,编译器还会为每个 FixMemoryStreamWithBuffer<> 类型实例以及继承链中的每个类生成单独的 v 表(以及 RTTI 信息)。

为了解决这个问题,我建议使用包含而不是继承,并在其中包含一些转换函数和/或运算符:

    template<size_t bufferSize> 
class FixedMemoryStreamWithBuffer
{
uint8_t buffer[bufferSize];
FixedMemoryStream m_stream;
public:
explicit FixedMemoryStreamWithBuffer() : m_stream(m_buffer, bufferSize) {}
operator FixedMemoryStream&() { return m_stream; }
FixedMemoryStream& toStream() { return m_stream; }
};

关于c++11 - 如何避免模板实例化和符号表导致的C++代码膨胀?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47893615/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com