C++ 模板:说服自己反对代码膨胀

2022-01-17 00:00:00 templates g++ compiler-construction c++

我听说过 C++ 模板上下文中的代码膨胀.我知道现代 C++ 编译器并非如此.但是,我想构建一个例子并说服自己.

假设我们有一个类

模板<类型名 T, size_t N >类数组 {上市:T * 数据();私人的:电文_[N];};模板<类型名 T, size_t N >T * 数组::data() {返回 elems_;}

此外,假设 types.h 包含

typedef 数组

整数,100 >我的数组;

x.cpp 包含

MyArray ArrayX;

y.cpp包含

MyArray ArrayY;

现在,如何验证 MyArray::data() 的代码空间对于 ArrayXArrayY 是否相同?

我还应该从这个(或其他类似的简单)示例中了解和验证什么?如果有任何 g++ 特定的提示,我也对此感兴趣.

PS:关于膨胀,我什至担心最轻微的膨胀,因为我来自嵌入式上下文.

<小时>

补充:如果模板类被显式实例化,情况是否会发生变化?

解决方案

您问错了问题 - 您的示例中的任何膨胀"都与模板无关.(顺便说一句,您的问题的答案是获取两个模块中成员函数的地址,您会发现它们是相同的)

您真正想问的是,对于每个模板实例化,生成的可执行文件是否线性增长?答案是否定的,链接器/优化器会变魔术.

编译一个创建一种类型的exe:

数组

整数,100 >我的数组;

注意生成的 exe 大小.现在再做一次:

数组

整数,100 >我的数组;数组<整数,99 >我的数组;

等等,对于大约 30 个不同的版本,绘制生成的 exe 大小图表.如果模板像人们想象的那样可怕,那么每个唯一模板实例化的 exe 大小都会以固定的量增长.

I have heard about code bloats in context of C++ templates. I know that is not the case with modern C++ compilers. But, I want to construct an example and convince myself.

Lets say we have a class

template< typename T, size_t N >
class Array {
  public:
    T * data();
  private:
    T elems_[ N ];
};

template< typename T, size_t N >
T * Array<T>::data() {
    return elems_;
}

Further, let's say types.h contains

typedef Array< int, 100 > MyArray;

x.cpp contains

MyArray ArrayX;

and y.cpp contains

MyArray ArrayY;

Now, how can I verify that the code space for MyArray::data() is same for both ArrayX and ArrayY?

What else I should know and verify from this (or other similar simple) examples? If there is any g++ specific tips, I am interested for that too.

PS: Regarding bloat, I am concerned even for the slightest of bloats, since I come from embedded context.


Addition: Does the situation change anyhow if the template classes are explicitly instantiated?

解决方案

You're asking the wrong question - any "bloat" in your example has nothing to do with templates. (the answer to your question, btw, is to take the address of the member function in both modules and you'll see they're the same)

What you really want to ask is, for each template instantiation, does the resulting executable grow linearly? The answer is no, the linker/optimizer will do magic.

Compile an exe that creates one type:

Array< int, 100 > MyArray;

Note the resulting exe size. Now do it again:

Array< int, 100 > MyArray;
Array< int, 99 > MyArray;

And so on, for 30 or so different versions, charting the resulting exe sizes. If templates were as horrible as people think, the exe size would grow by a fixed amount for each unique template instantiation.

相关文章