When you use a template with numerous methods (like vector) and compile your code, will the compiler discard the code from the unused methods?
A template is not instantiated unless it is used, so there is actually no code to discard.
The standard says (14.7.1/10)
An implementation shall not implicitly instantiate a function template, a member template, a non-virtual member function, a member class, or a static data member of a class template that does not require instantiation. It is unspecified whether or not an implementation implicitly instantiates a virtual member function of a class template if the virtual member function would not otherwise be instantiated. The use of a template specialization in a default argument shall not cause the template to be implicitly instantiated except that a class template may be instantiated where its complete type is needed to determine the correctness of the default argument. The use of a default argument in a function call causes specializations in the default argument to be implicitly instantiated.
So if you can avoid making the template's member functions virtual, the compiler will not generate any code for them (and that might work for virtual functions as well, if the compiler is smart enough).
It depends on your optimization level. At higher optimization settings, yes, dead code elimination will most likely occur.
the compiler, optimizers, and the linker can omit and/or reduce that information. each mature tool likely has options specific to dead code elimination.
with templates, the code may not really be created in the first place (unless instantiated).
certainly not all of it will be removed in every scenario, however (rtti is a silent killer). a bit of caution and testing using your build settings can go a long way to help you reduce the binary sizes and dead code.
Smart compilers will exclude it most likely. Long time ago when I played with Borland C++ Builder, I think, it did not throw out unused template class methods. Can not confirm though
Related
Does a C++ compiler generates code if a function template or a class template is specialized but not actually used? I know it will not, if not specialized (function or class template) and not used.
--Thanks
Technically the compiler may choose to eliminate your specialization since it's elimination would not affect the observable behavior of your program. See the as-if rule. Compilers generally provide facilities for exporting symbols such that they are preserved even if unused.
I'm reading C++ Primer, and it says:
"If a member function isn't used, it is not instantiated. The fact that members are instantiated only if we use them lets us instantiate a class with a type that may not meet the requirements for some of the template’s operations."
I don't know why this is a problem. If some operations are required, why doesn't compiler instantiate those operations? Can someone give an example?
That's an ease-of-use feature, not a pitfall.
Lazy instantiation serves to simplify templates. You can implement the set of all possible member functions that any specialization might have, even if some of the functions don't work for some specializations.
It also reduces compile time, since the compiler never needs to instantiate what you don't use.
To prevent lazy instantiation, use explicit instantiation:
template class my_template< some_arg >;
This will immediately instantiate all the members of the class (except members which are templates, inherited, or not yet defined). For templates that are slow to compile, you can do the above in one source file (translation unit) and then use the linker to bypass instantiation in other source files, by putting a declaration in the header:
extern template class my_template< some_arg >;
The Wikipedia article says this:
instantiating a class template does not cause its member definitions to be instantiated.
I can't imagine any class in C++ being instantiated, whether from a template or not, where that classes members were not also instantiated?
Many early C++ compilers instantiated all member functions, whether you ever called them or not.
Consider, for example, std::list, which has a sort member function. With a current, properly functioning compiler, you can instantiate list over a type that doesn't support comparison. If you try to use list::sort, it will fail, because you don't support comparison. As long as you don't call sort for that list, it's all fine though, because list<T>::sort won't be instantiated unless you call it.
With those older, poorly functioning compilers, however, trying to create list<T> meant that list<T>::sort was instantiated even though you never used it. The existence of list::sort meant that you needed to implement < for T, just to create a list<T>, even if you never actually used sort on a list of that type at all.
The standard clearly says that (both non-template and template) member methods instantiation should happen only when used.
An excerpt from C++ standard (N3690 - 14.7.1(2) Implicit instantiation)
2 Unless a member of a class template or a member template has been explicitly instantiated or explicitly specialized, the specialization of the member is implicitly instantiated when the specialization is referenced in a context that requires the member definition to exist; in particular, the initialization (and any associated side-effects) of a static data member does not occur unless the static data member is itself used in a way that requires the definition of the static data member to exist.
Methods of a class are also members. Class Template methods are instantiated when they are called for that instantiated class. So it is possible that those member methods are never instantiated.
Note: This is a follow-up question to this.
I have a group of template classes that do completely different things in completely different ways using completely different datatypes. They do, however, share common method names. For example, Get(), Set(), Resize(), etc. are valid methods for each of the classes in question. Additionally, they accept arguments in the same order. This allows for generalized non-friend, non-member functions to work on each of the classes. A simplified example:
template <typename Class, typename Datatype>
void Insert(const Class<Datatype>& Object, const std::size_t Index, const Datatype Value)
{
Object.Resize(Object.Size() + 1);
for (std::size_t CurrentIndex = Object.Size() - 1; CurrentIndex > Index; CurrentIndex--)
{
Object.Set(CurrentIndex, Object.Get(CurrentIndex - 1));
}
Object.Set(Index, Value);
}
Right now, I'm just relying on my own memory to define all the appropriate methods properly. Is there a way to have the compiler enforce the definition of the proper methods? If not, is there a better way to do this?
What you are looking for is called "concepts" and used to be a feature in C++0x but got dropped from the new standard.
There are some implementations for C++03 out there, but they are harder to use and might be not worth the trouble. e.g. Boost Concept Checking
gcc also has the --enable-concept-check option although I'm not entirely sure how that works with user code.
The compiler already enforces the definition of those methods by refusing to let you instantiate the template for types that don't provide the necessary methods.
Unfortunately, compilers' error messages for uninstantiable templates are often difficult to decipher.
You can document the type requirements in comments. Take a look at how the C++ standard defines type requirements like Assignable, CopyConstructible, EqualityComparable, LessThanComparable, and the requirements for types in the standard containers.
The compiler will enforce the correct interface by failing to compile any call to a nonexistent function; perhaps the problem is that the error messages are too cryptic?
You could define a base class which declares the required interface as non-virtual functions. The base class functions have no definitions (except where it makes sense to have an optional function with a default implementation).
Then, if the template argument derives from this base class, failure to implement a required function will cause a link error (due to attempting to call the base class functions, which are not defined). This will most likely be easier to diagnose than a typical template-related compile error.
You could go one step further and include a compile-time check that the template argument is derived from the base class; I'll leave that as an exercise for the reader. Or it might be better to just document the purpose of the base class, and leave it up to the user whether to use it or not.
You can use an interface.
See this question: How do you declare an interface in C++?
I know that Function Templates are used so as to make the functions portable and so that they could be used with any data types.
Also Explicit Specialization of templates is done if we have a more efficient implementation for a specific data type.
But then instead of Explicit Specialization we could also just code a Nontemplate Function which could be called from main .
This would save us some processing time as the compiler would locate Nontemplate Functions faster than Explicitly Specialized Templated Functions which would in turn be better in terms of efficiency.
So why do we use Explicit Specialization when we have the alternative of just calling Nontemplate Functions?
Please correct me If I'm wrong!
Edit 1:
I was told by my professor that whenever we make function templates and call the function from main ,the compiler first looks for a templated function and if its not able to locate that,then it searches for a function template from which it in turn makes a templated function and then calls for it.
This would save us some processing time as the compiler would locate Global Functions faster than Explicitly Specialized Templated Functions which would in turn be better in terms of efficiency.
Why would the compiler find a nontemplate function faster than a function template specialization? Have you benchmarked compiler performance to verify this statement? If you use a function named f, the compiler always has to compile a set of candidate functions and perform overload resolution to determine the correct function to be used.
At runtime (which is when performance really matters, right?) the performance of calling a function template instantiation should be no better than the performance of calling a nontemplate function.
So why do we use Explicit Specialization when we have the alternative of just calling Global Functions?
In the general case, for function templates, you don't use explicit specialization, because it's usually confusing and difficult. The ISO C++ standard has a poetic warning to be extremely cautious when specializing function templates. You can read Herb Sutter's "Why Not Specialize Function Templates?" for a good explanation of the issues and why you don't want to specialize function templates.
It sounds like you're confusing compile-time efficiency with run-time efficiency. The choice of which function to call is made at compile time, not run time, so it will make no difference to the run time of the program.
Explicit Specialization is used when you have a special case that can benefit from special treatment. Sometimes this backfires, as in the case of std::vector<bool>, while other times it's quite handy. It means that the user of the function doesn't need to be aware that there's a special case; it's just transparent.
For reasons of uniformity. The person using the API just calls methods with particular arguments, some get the generic function some get explicitly specialised functions - the client need neither know nor care which they use.