4 ms·
I'm not sure what purpose your desire would serve, or even if it makes sense. For example, this is a contradiction: "I wish the compiler could aggressively look
by scott_s 11y ago
I'm not sure what purpose your desire would serve, or even if it makes sense. For example, this is a contradiction: "I wish the compiler could aggressively look for and link to instances that have the same binary representation - even if they have disparate type information."
The generated object code for thing<int> and thing<double> are likely to not be identical, except for where the types are manipulated. Because thing<int> and thing<double> generate entirely different classes, they can actually be radically different. First, C++'s resolution rules allow them to be actually different C++ code. But even if it reuses the C++ code, because that code then goes through the optimization phases, what comes out the other side may not have the kind of trivial relationship you're thinking of.
I don't think this is unique to C++; it should be true of any language that has non-type erased generics that generates native code. I'm thinking of Haskell, OCaml and Rust - but if people who know those languages and compiler chain better think I'm wrong, please speak up.
Personally, I find C++'s templates to be extremely useful and powerful. I also think they are demonstrably not as nearly as hackish as the C preprocessor, as evidenced by the fact that they actually have knowledge of types. The C preprocessor is just textual substitution, while C++'s templates are far, far from that.
- catnaroek 11y agoTo the best of my knowledge, (GHC) Haskell and OCaml don't need to monomorphize parametrically polymorphic code, because they use a uniform representation for most objects. Some features of these languages, like GADTs and polymorphic recursion, are difficult to reconcile with monomorphization anyway. On the other hand, Rust generics are monomorphized at compile time, which is closer to how C++ templates work. (The most important difference is that Rust generics are type-checked at definition time, rather than instantiation time.) Another language implementation that uses compile-time monomorphization is MLton, a whole-program Standard ML compiler. Ideally, the language should offer the programmer two kinds of polymorphism: (0) second-class, which is less expressive but easier to type-check and more amenable to optimization, (1) first-class, with the opposite tradeoff.
- coroutines 11y agoI mean to say, the compiler might see std::vector<a> and std::vector<b> as strictly separate types, but at their base/binary might be code that is identical (effectively std::vector<int>). I am imagining that the compiler would generate code for both, and not see the opportunity to deduplicate identical object code. Again, I suspect I am naive here.
- scott_s 11y agoI think you're saying that a and b are actually typedefs to the same type. Yes, in that case I believe C++ compilers are smart enough to share code.
- catnaroek 11y agoIf `a` and `b` are typedefs to the same type, then `foo<a>` and `foo<b>` are literally the same type, so sharing code isn't a matter of compilers being “smart” - it's a matter of respecting C++'s semantics. I think GP is talking about something different. Let's say you have two completely unrelated types `a` and `b`, but, for whatever reason, `foo<a>` and `foo<b>` happen to compile to exactly the same machine code. (For a concrete example, say `a` and `b` have the same size and alignment requirements, and say `foo` is `std::vector::reserve`.) Then either the compiler or the linker can “merge” the duplicated code for `foo<a>` and `foo<b>`.
- coroutines 11y agoThat is not what I'm saying. Example: You can have 2 struct types that each only contain an int with the same member name. They would [likely] have the same binary representation. You could then create 2 vector types specialized for each struct type. The code for both vectors would handle the data in the same way - but the compiler would view the vector types as _STRICTLY_ separate types. I do not think this code would be uniquely shared - the compiler would generate code for both vector types.
- scott_s 11y agoNow I get what you're saying. I think it's possible for a C++ compiler to be smart about this. But why is this such a big deal to you? Have you seen it become an issue in projects you've worked on?