2nd phase compilation in templates - c++

I am trying to understand the compilation process and the code generation process in c++ template universe.
I have read that during the first phase of compilation only the basic syntax is checked(in templated code).
And that the actual code is generated only for those data types which are used for which the compilation is done completely- this is termed as second phase compilation.
I am not able to understand that how can a compiler know for which data type can the templated code be called and for which to generate the code(and hence do 2nd phase compilation). There might be cases when the function calls(in case off function templates) might not be so strightforward to derive the datatype during compile time, these can be derived only during runtime basedon input from user.
Assuming i have a written a huge code using templates with a lot of conditions based on which it generates new instance of templated code(lets say new instance of datatype for a class). I cant test the code for all the data types. So does it mean that if i test it for a couple of data types, there are still chances of my code failing unexpectedly for some other data types? If so, how can i ensure to force 2nd compilation for all the data types(irrespective of that data type based on my input is instantiated or not).

The types determined during compilation time only rely on the static information. A function template that is used with a particular type will generate code for that type, since the option needs to be available in the runtime. If it can be statically determined that a function call will never happen, though, I think that the compiler might omit that implementation, but there are certain cases that'd still force that.
You can't test for all datatypes, since that's an infinite set. You can create a set of all standard types, but you obviously can't check every user-defined type ever. The idea in generic code is to not depend on the particulars of the type you're allowing to pass it. Alternatively, you might close the set of possible instances to only include the types you sanction.

I am not able to understand that how can a compiler know for which data type can the templated code be called
The compiler knows for which data types the templated code is actually called because it sees every place in the program where the templated code is actually called. No magic here. Instantiation happens at call sites. No instantiation is done for types that are not used in actual existing calls.
there are still chances of my code failing
This is true for all test-based validation, templates or no templates, and even for things other than software. You cannot cover all possible use cases by tests. It's a fundamental fact of life. Deal with it... somehow.

Related

C++ Templates: Are template ínstantiations inlined? Are there drawbacks in performance?

When some C++ entity, such as a structure, class, or function, is declared as a template, then the definitions provided for said entities are solely blue-prints which must be instantiated.
Due to the fact that a template entity must be defined when it is declared (which is commonly header files) I have the conception, which I try to convince myself as wrong, that when after a template has been instantiated it will be inlined by the compiler. I would like to ask if this is so?
The answer for this question raises my suspicion when I read the the paragraph:
"Templates can lead to slower compile-times and possibly larger
executable, especially with older compilers."
Slower compile-times are clear as template must be instantiated but why "possibly larger executables"? In what ways should this be interpreted? Should I interpret this as 'many functions are inlined' or 'the executable's size increases if there are many template instantiations, that is the same template is instantiated with a lot of different types, which causes several copies of the same entity to be there'?
In the latter case, does a larger executable size cause the software to run more slowly seeing that more code must be loaded into memory which will in turn cause expensive paging?
Also, as these questions are also somewhat compiler dependent I am interested in the Visual C++ compiler. Generalised answers concerning what most compilers do give a good insight as well.
Thank you in advance.
Due to the fact that a template entity must be defined when it is declared (which is commonly header files)
Not true. You can declare and define template classes, methods and functions separately, just like you can other classes, methods and functions.
I have the conception, which I try to convince myself as wrong, that when after a template has been instantiated it will be inlined by the compiler. I would like to ask if this is so?
Some of it may be, or all of it, or none of it. The compiler will do what it deems is best.
Slower compile-times are clear as template must be instantiated but why "possibly larger executables"? In what ways should this be interpreted?
It could be interpreted a number of ways. In the same way that a bottle of Asprin contains the warning "may induce <insert side-effects here>".
Should I interpret this as 'many functions are inlined' or 'the executable's size increases if there are many template instantiations, that is the same template is instantiated with a lot of different types, which causes several copies of the same entity to be there'?
You won't have several copies of the same entity - the compiler suite is obliged to see to that. Even if methods are inline, the address of the method will:
always exist, and
be the same address when referenced by multiple compilation units.
What you may find is that you start creating more types than you intended. For example std::vector<int> is a completely different type to std::vector<double>. foo<X>() is a different function to foo<Y>(). The number of types and function definitions in your program can grow quickly.
In the latter case, does a larger executable size cause the software to run more slowly seeing that more code must be loaded into memory which will in turn cause expensive paging?
Excessive paging, probably not. Excessive cache misses, quite possibly. Often, optimising for smaller code is a good strategy for achieving good performance (under certain circumstances such as when there is little data being accessed and it's all in-cache).
Whether they are inlined is always up to the compiler. Non-inlined template instantiations are shared for all similar instantiations.
So a lot of translation units all wanting to make a Foo<int> will share the Foo instantiation. Obviously if Foo<int> is a function, and the compiler decides in each case to inline it then the code is repeated. However the choice to inline is because the optimization of doing so seems highly likely to be superior to a function call.
Technically there could be a corner case where a template causes slower execution. I work on software which has super tight inner loops for which we do a lot of performance measurements. We use a number of template functions and classes and it has yet to show up a degradation compared to writing the code by hand.
I can't be certain but I think you'd have to have a situation where the template:
- generated non-inlined code
- did so for multiple instantiations
- could have been one hand-written function
- hand-written function incurs no run-time penalty for being one function (ie: no implicit conversions involving runtime checks)
Then it's possible that you have a case where the single-handwritten-function fits within the CPU's instruction cache but the multiple template instantiations do not.

compilation control and code bloat in templates

I am reading about templates in apllied C++ book and it is mentioned as below
Templates create code bloat. The compiler will instantiate a template
object for each pixel type. Even if your users only need limited
types, the image processing routines may need additional types for
temporary images and the like.
Not having to be templated object has the advantage of giving us
control of how the object will be compiled, and lets us control code
bloat.
My questions on above text
What does author mean by "Even if your users only need limited types, the image processing routines may need additional types for temporary images and the like." ?
What does author mean by "Not having to be templated object has the advantage of giving us control of how the object will be compiled" ?
Request your help in understanding above statements. It would be good if explained with simple examples.
Thanks for your time and help.
The author is right that templates may create so-called code-bloat, but his explanations are fuzzy...
Let us a start with a primer on code-bloat.
There is an annoying interaction in the C++ Standard between templates and function pointers:
Each instantiation of a template with a given set of parameters is its own types
Two different functions should have different addresses
Since two different instantiations (one with int and one with long for example) are different types, the functions associated with them are different functions, and thus they need different addresses.
An optimizing compiler is allowed to actually merge functions under the as-if rule: if the programmer cannot realize they were merged. The naive attempt is to try and prove that the address of one of them is never taken, this is futile. A more clever strategy is to merge the function bodies, but still provide a different address:
; assembly-like code
function_instantiation_1:
nop ; offset to have different addresses
function_instantiation_2:
; body of both functions
However a practical problem is to identify such functions that could be merged, given the sheer number of functions there are.
So ? If one wishes to limit the amount of code produced, one just has to limit the number of instantiations. I find the author claim that the image processing routines may need additional types for temporary images and the like dubious. The set of types within a program is generally fairly restricted, and there are not gazillions of image types.

Will C++ compiler generate code for each template type?

I have two questions about templates in C++. Let's imagine I have written a simple List and now I want to use it in my program to store pointers to different object types (A*, B* ... ALot*). My colleague says that for each type there will be generated a dedicated piece of code, even though all pointers in fact have the same size.
If this is true, can somebody explain me why? For example in Java generics have the same purpose as templates for pointers in C++. Generics are only used for pre-compile type checking and are stripped down before compilation. And of course the same byte code is used for everything.
Second question is, will dedicated code be also generated for char and short (considering that they both have the same size and there are no specialization).
If this makes any difference, we are talking about embedded applications.
I have found a similar question, but it did not completely answer my question: Do C++ template classes duplicate code for each pointer type used?
Thanks a lot!
I have two questions about templates in C++. Let's imagine I have written a simple List and now I want to use it in my program to store pointers to different object types (A*, B* ... ALot*). My colleague says that for each type there will be generated a dedicated piece of code, even though all pointers in fact have the same size.
Yes, this is equivalent to having both functions written.
Some linkers will detect the identical functions, and eliminate them. Some libraries are aware that their linker doesn't have this feature, and factor out common code into a single implementation, leaving only a casting wrapper around the common code. Ie, a std::vector<T*> specialization may forward all work to a std::vector<void*> then do casting on the way out.
Now, comdat folding is delicate: it is relatively easy to make functions you think are identical, but end up not being the same, so two functions are generated. As a toy example, you could go off and print the typename via typeid(x).name(). Now each version of the function is distinct, and they cannot be eliminated.
In some cases, you might do something like this thinking that it is a run time property that differs, and hence identical code will be created, and the identical functions eliminated -- but a smart C++ compiler might figure out what you did, use the as-if rule and turn it into a compile-time check, and block not-really-identical functions from being treated as identical.
If this is true, can somebody explain me why? For example in Java generics have the same purpose as templates for pointers in C++. Generics are only used for per-compile type checking and are stripped down before compilation. And of course the same byte code is used for everything.
No, they aren't. Generics are roughly equivalent to the C++ technique of type erasure, such as what std::function<void()> does to store any callable object. In C++, type erasure is often done via templates, but not all uses of templates are type erasure!
The things that C++ does with templates that are not in essence type erasure are generally impossible to do with Java generics.
In C++, you can create a type erased container of pointers using templates, but std::vector doesn't do that -- it creates an actual container of pointers. The advantage to this is that all type checking on the std::vector is done at compile time, so there doesn't have to be any run time checks: a safe type-erased std::vector may require run time type checking and the associated overhead involved.
Second question is, will dedicated code be also generated for char and short (considering that they both have the same size and there are no specialization).
They are distinct types. I can write code that will behave differently with a char or short value. As an example:
std::cout << x << "\n";
with x being a short, this print an integer whose value is x -- with x being a char, this prints the character corresponding to x.
Now, almost all template code exists in header files, and is implicitly inline. While inline doesn't mean what most folk think it means, it does mean that the compiler can hoist the code into the calling context easily.
If this makes any difference, we are talking about embedded applications.
What really makes a difference is what your particular compiler and linker is, and what settings and flags they have active.
The answer is maybe. In general, each instantiation of a
template is a unique type, with a unique implementation, and
will result in a totally independent instance of the code.
Merging the instances is possible, but would be considered
"optimization" (under the "as if" rule), and this optimization
isn't wide spread.
With regards to comparisons with Java, there are several points
to keep in mind:
C++ uses value semantics by default. An std::vector, for
example, will actually insert copies. And whether you're
copying a short or a double does make a difference in the
generated code. In Java, short and double will be boxed,
and the generated code will clone a boxed instance in some way;
cloning doesn't require different code, since it calls a virtual
function of Object, but physically copying does.
C++ is far more powerful than Java. In particular, it allows
comparing things like the address of functions, and it requires
that the functions in different instantiations of templates have
different addresses. Usually, this is not an important point,
and I can easily imagine a compiler with an option which tells
it to ignore this point, and to merge instances which are
identical at the binary level. (I think VC++ has something like
this.)
Another issue is that the implementation of a template in C++
must be present in the header file. In Java, of course,
everything must be present, always, so this issue affects all
classes, not just template. This is, of course, one of the
reasons why Java is not appropriate for large applications. But
it means that you don't want any complicated functionality in a
template; doing so loses one of the major advantages of C++,
compared to Java (and many other languages). In fact, it's not
rare, when implementing complicated functionality in templates,
to have the template inherit from a non-template class which
does most of the implementation in terms of void*. While
implementing large blocks of code in terms of void* is never
fun, it does have the advantage of offering the best of both
worlds to the client: the implementation is hidden in compiled
files, invisible in any way, shape or manner to the client.

template and executable file

Is it true that template code compiled and linked into a PE will increase in size compared to code without templates. I think each instances of templates used is packed orderly so it will output a match if required faster.
Sorry for the question I just don't know much about template.
C++ works on the principle:
You pay for what you use.
Template code creates binaries only for the code that you use/Instantiate.
Just because you compile against Standard Library which has hundreds of STL containers it does not mean your object code includes all of them, It only includes the ones you use.
Templates implement compile time polymorphism. An copy of templated function is created for every instantiation you do with different data type, same is the case for templated classes. This code is further compiled to create binaries. So the size of the binary will not be any bigger than what your code without templates would produce.
The template itself doesn't take any space at all. It the instantiations of that template that do. A template is instantiated once you use it with a type parameter - MyClass<int> mc. An instantiation is created once for every type you use, so MyClass<int> mc2 won't cause another instantiation, but rather use the existing one.
So it really depends on how many types you use with the templates. But that's no different that using different non-templated classes, which will also increase your code size. Bottom line - I wouldn't worry about it.
In addition to answers given by #Als and #eran:
Compiler and Linker would work collectively to find out code that is same for two or different data types for given class/functions, and if they find out similar code, that is not-dependent on datatype, they may create one copy of that code. The code might be a method of class, certain function or some part of method/function.

C++ Template Specialization Compilation

I'm going to outline my problem in detail to explain what I'm trying to achieve, the question is in the last paragraph if you wish to ignore the details of my problem.
I have a problem with a class design in which I wish to pass a value of any type into push() and pop() functions which will convert the value passed into a string representation that will be appended to a string inside the class, effectively creating a stream of data. The reverse will occur for pop(), taking the stream and converting several bytes at the front of the stream back into a specified type.
Making push() and pop() templates tied with stringstream is an obvious solution. However, I wish to use this functionality inside a DLL in which I can change the way the string is stored (encryption or compression, for example) without recompilation of clients. A template of type T would need to be recompiled if the algorithm changes.
My next idea was to just use functions such as pushByte(), pushInt(), popByte(), popInt() etc. This would allow me to change the implementation without recompilation of clients, since they rely only on a static interface. This would be fine. However, it isn't so flexible. If a value was changed from a byte to a short, for example, all instances of pushByte() corresponding to that value would need to be changed to pushShort(), similarly for popByte() to popShort(). Overloading pop() and push() to combat this would cause conflictions in types (causing explicit casting, which would end up causing the same problem anyway).
With the above ideas, I could create a working class. However, I wondered how specialized templates are compiled. If I created push<byte>() and push<short>(), it would be a type specific overload, and the change from byte to short would automatically switch the template used, which would be ideal.
Now, my question is, if I used specialized templates only to simulate this kind of overloading (without a template of type T), would all specializations compile into my DLL allowing me to dispatch a new implementation without client recompilation? Or are specialized templates selected or dropped in the same way as a template of type T at client compilation time?
First of all, you can't just have specialized templates without a base template to specialize. It's just not allowed. You have to start with a template, then you can provide specializations of it.
You can explicitly instantiate a template over an arbitrary set of types, and have all those instantiations compiled into your DLL, but I'm not sure this will really accomplish much for you. Ultimately, templates are basically a compile-time form of polymorphism, and you seem to need (at least a limited form of) run-time polymorphism.
I'd probably just use overloading. The problem that I'd guess you're talking about arises with something on the order of:
int a;
byte b;
a = pop();
b = pop();
Where you'd basically just be overloading pop on the return type (which, as we all know, isn't allowed). I'd avoid that pretty simply -- instead of returning the value, pass a reference to the value to be modified:
int a;
byte b;
pop(a);
pop(b);
This not only lets overload resolution work, but at least to me looks cleaner as well (though maybe I've just written too much assembly language, so I'm accustomed to things like "pop ax").
It sounds like you have 2 opposing factors:
You want your clients to be able to push/pop/etc. every numeric type. Templates seem like a natural solution, but this is at odds with a consistent (only needs to be compiled once) implementation.
You don't want your clients to have to recompile when you change implementation aspects. The pimpl idiom seems like a natural solution, but this is at odds with a generic (works with any type) implementation.
From your description, it sounds like you only care about numeric types, not arbitrary T's. You can declare specializations of your template for each of them explicitly in a header file, and define them in a source file, and clients will use the specializations you've defined rather than compiling their own. The specializations are a form of compile time polymorphism. Now you can combine it with runtime polymorphism -- implement the specializations in terms of an implementation class that is type agnostic. Your implementation class could use boost::variant to do this since you know the range of possible T's ahead of time (boost::variant<int, short, long, ...>). If boost isn't an option for you, you can come up with a similar scheme yourself so long as you have a finite number of Ts you care about.