C++ Templates: Convincing self against code bloat

前端 未结 7 1054
暖寄归人
暖寄归人 2020-12-09 18:08

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.

7条回答
  •  -上瘾入骨i
    2020-12-09 18:48

    Templates have nothing to do with that.

    Consider this small program:

    a.h:

    class a {
        int foo() { return 42; }
    };
    

    b.cpp:

    #include "a.h"
    
    void b() {
      a my_a;
      my_a.foo();
    }
    

    c.cpp:

    #include "a.h"
    
    void c() {
      a my_a;
      my_a.foo();
    }
    

    There are no templates, but you have the exact same problem. The same function is defined in multiple translation units. And the rule is the same: only one definition is allowed to exist in the final program, otherwise the compiler wouldn't be able to determine which one to call, and otherwise two function pointers pointing to the same function may point to different addresses.

    The "problem" with template code bloat is something different: it is if you create a lot of different instantiations of the same template. For example, using your class, this program will risk some code bloat:

    Array< int, 100 > i100;
    Array< int, 99 > i99;
    Array< long, 100 > l100;
    Array< long, 99> l99;
    
    i100.Data();
    i99.Data();
    l100.Data();
    l99.Data();
    

    Strictly speaking, the compiler is required to create 4 different instantiations of the Data function, one for each set of template parameters. In practice, some (but not all) compilers try to merge them back together, as long as the generated code is identical. (In this case, the assembly generated for Array< int, 100 > and Array< long, 100 > would be identical on many platforms, and the function doesn't depend on the array size either, so the 99 and 100 variants should also produce identical code, so a clever compiler will merge the instantiations back together.

    There is no magic to templates. They don't mysteriously "bloat" your code. They just give you a tool that lets you easily create a bajillion different types from the same template. If you actually use all of these types, it has to generate code for all of them. As always with C++, you pay for what you use. If you use both an Array, an Array, an Array and an Array, then you get four different classes, because four different classes was what you asked for. If you don't ask for four different classes, they don't cost you anything.

提交回复
热议问题