Symbol table entry for templates - c++

I have doubt about template functions.
If i write a normal function like
int function1(int x);
int function1(int x, int y);
two symbol table entry will be made for function1.
each entry represents each overloaded function.
In case of template function, what exactly happens and how it is handled by the compiler.
template<class X>
int function1(X a);
How many symbol table entries will be present for template functions?

There is no such thing as a "template function" in C++. There are "function templates," that is, templates (or perhaps blueprints) for creating functions. Once you accept this, the answer becomes easier to discover.
A template is purely a compilation construct. Each function instantiated from the template is (naturally) a function and thus it will have its own symbol.
Just as with inline functions, if one and the same function (= using the same set of template arguments) is instantiated from the template in different translation units (= different .cpp files), the compiler & linker must ensure these are merged into one, because their addresses must be the same. How they do it is an implementation detail of theirs; the standard just mandates that they have to do it. And I am afraid I don't know the technical details of how this can be done, so I can't provide an example.

When you create an instance of the function template using specific template parameter, the compiler generates one overloaded method. So when you use the method
temlate<class X>
int function1(X a);
to use like
function1<int>(5);
function1<double>(5.0);
Compiler generates
int function1(int a);
int function1(double a);
These are overloaded and there will be 2 symbols.
In fact templates are much like macro, with strong type checking. At compile type function templates are replaced with actual instance. In object code there is no existence of the template function, only the instantiate overloads (if any).

In the case that nobody is using the template to create a compiled function, in fact no entry is created in the symbol table. Otherwise, for each different use of the template (for each type or type combination—in case there are several type parameters to it) one more compiled function and thus one more entry in the symbol table is created.
Templates are evaluated on compile time only; after compiling they do not exist anymore.

For sure "one for each instantiation".
A function template by itself is not a type, or a function, or any other entity.
No code is generated from a source file that contains only template definitions.
In order for any code to appear, a template must be instantiated: the template
arguments must be determined so that the compiler can generate an actual function
link

Related

What does the compiler do when you make a function template? [duplicate]

I'm reading a book about how templates work, and I'm having difficulty understanding this explanation of templates.
It says
When the compiler sees the definition of a template, it does not generate code. It generates code only when we instantiate a specific instance of the template. The fact that code is generated only when we use a template (and not when we define it) affects how we organize our source code and when errors are detected...To generate an instantiation, the compiler needs to have the code that defines a function template or class template member function. As a result, unlike non-template code, headers for templates typically include definitions as well as declarations.
What exactly does it mean by "generate code"? I don't understand what is different when you compile function templates or class templates compared to regular functions or classes.
The compiler generates the code for the specific types given in the template class instantiation.
If you have for instance a template class declaration as
template<typename T>
class Foo
{
public:
T& bar()
{
return subject;
}
private:
T subject;
};
as soon you have for example the following instantiations
Foo<int> fooInt;
Foo<double> fooDouble;
these will effectively generate the same linkable code as you would have defined classes like
class FooInt
{
public:
int& bar()
{
return subject;
}
private:
int subject;
}
and
class FooDouble
{
public:
double& bar()
{
return subject;
}
private:
double subject;
}
and instantiate the variables like
FooInt fooInt;
FooDouble fooDouble;
Regarding the point that template definitions (don't confuse with declarations regardless of templates) need to be seen with the header (included) files, it's pretty clear why:
The compiler can't generate this code without seeing the definition. It can refer to a matching instantiation that appeared first at linking stage though.
What does a non-template member function have that allows for it to
be defined outside of the header that a template function doesn't
have?
The declaration of a non-template class/member/function gives a predefined entry point for the linker. The definition can be drawn from a single implementation seen in a compiled object file (== .cpp == compilation unit).
In contrast the declaration of a templated class/member/function might be instantiated from arbitrary compilation units given the same or varying template parameters. The definition for these template parameters need's to be seen at least once. It can be either generic or specialized.
Note that you can specialize template implementations for particular types anyway (included with the header or at a specific compilation unit).
If you would provide a specialization for your template class in one of your compilation units, and don't use your template class with types other than specialized, that also should suffice for linking it all together.
I hope this sample helps clarifying what's the difference and efforts done from the compiler.
A template is a pattern for creating code. When the compiler sees the definition of a template it makes notes about that pattern. When it sees a use of that template it digs out its notes, figures out how to apply the pattern at the point where it's being used, and generates code according to the pattern.
What is the compiler suppose to do when it sees a template? Generate all the machine code for all possible data types - ints, doubles, float, strings, ... Could take a lot of time. Or just be a little lazy and generate the machine code for what it requires.
I guess the latter option is the better solution and gets the job done.
The main point here is that compiler does not treat a template definition until it meets a certain instance of the template. (Then it can proceed, I guess, like it have a usual class, which is a specific case of the template class, with fixed template parameters.)
The direct answer to your question is: Compiler generates machine code from users c++ code, I think this is wat is meant here by word "generate code".
The template declaration must be in header file because when compiler compiles some source, which use template it HAVE only header file (included in source with #include macro), but it NEED whole template definition. So logical conclusion is that template definition must be in header.
When you create a function and compile it, the compiler generates code for it. Many compilers will not generate code for static functions that are not used.
If you create a templated function and nothing uses the template (such as std::sort), the code for the function will not be generated.
Remember, templates are like stencils. The templates tell how to generate a class or function using the given template parameters. If the stencil is not used, nothing is generated.
Consider also that the compiler doesn't know how to implement or use the template until it sees all the template parameters resolved.
It won't straight away generate code. Only generates the class or template code when it comes across an instantiation of that template. That is, if you are actually creating an object of that template definition.
In essence, templates allow you abstract away from types. If you need two instantiations of the template class for example for an int and a double the compiler will literally create two of these classes for you when you need them. That is what makes templates so powerful.
Your C++ is read by the compiler and turned into assembly code, before being turned in machine code.
Templates are designed to allow generic programming. If your code doesn't use your template at all, the compiler won't generate the assembly code associated. The more data types you associate your template with in your program, the more assembly code it will generate.

Where are template functions instantiated?

I believe that there are 4 situations where my question may have different answers. These situations are sorted by member vs. non-member functions and within vs. without a library.
Non-member function within a library
Suppose that I have defined a template function func in header func.h.
// func.h
template <typename T>
int func(T t){
//definition
}
I #include "func.h" in two cpp files of the same project/library/executable and call
//a.cpp
#include "func.h"
//stuff
int m = func<int>(3);
//stuff
and
//b.cpp
#include "func.h"
//stuff
int n = func<int>(27);
//stuff
My understanding is that these two cpp files should compile into their own object files. In what object file is func<int> instantiated? Why will the One Definition Rule not be violated? For this basic application of templates, is there any benefit to explicitly instantiating func<int> separate from its use?
Member function within a library
Suppose that func is instead a member function of some class Func.
// func.h
class Func {
template <typename T>
int func(T t){
//definition
}
};
Where will func be instantiated? Will func<int> be linked to or placed inline?
Member and Non-Member functions across libraries
Suppose that a.cpp and b.cpp are in different libraries that are compiled separately and later linked into an executable. Will the different libraries their own definitions of func<int>? At link time, why will the One Definition Rule not be violated?
Note: There is a related question of the same title here, but in a specific situation with one cpp file.
In what object file is func<int> instantiated?
In every object file (aka translation unit) that invokes it or takes an address of it when the template definition is available.
Why will the One Definition Rule not be violated?
Because the standard says so in [basic.def.odr].13.
Also see https://en.cppreference.com/w/cpp/language/definition
There can be more than one definition in a program of each of the following: class type, enumeration type, inline function, inline variable (since C++17), templated entity (template or member of template, but not full template specialization), as long as all of the following is true...
For this basic application of templates, is there any benefit to explicitly instantiating func<int> separate from its use?
In this case you get no inlining but possibly smaller code. If you use link-time code generation, then inlining may still happen.
All your questions do not really differ when it comes to answer. Regardless of template function being a member or a free function, it is going to be instantiated on first use (with given types) in each compilation unit (.cpp file).
From the compiler standpoint, ODR is not violated here, since there are no two prohibited definitions of templated function. Standard explicitly allows several definitions of templated functions.
Yet your intuition that you end up with definition of instantiated function twice in object files is correct. Luckily, ODR doesn't apply at this point. Instead, those definitions are generated with so-called 'weak' symbol - telling linker that those two symbols are identical, and it is free to pick one (or none and perform link-time optimization!)

Why my C++ templated function does not produce `undeclared identified` compile error?

I am trying to create an abstraction about Lights (I'm building a game in C++) and I'm using templates to do that. A part of my code right now is:
// Light.hpp
template <typename LightType>
void LoadLight(GLuint shaderId, const LightType& light, const std::string& glslUniformName)
{
// Load common light attributes
glUniform3f(glGetUniformLocation(lightingShader.GetProgID(), (glslUniformName + ".ambient").c_str()), light.ambient.x, light.ambient.y, light.ambient.z);
glUniform3f(glGetUniformLocation(lightingShader.GetProgID(), (glslUniformName + ".diffuse").c_str()), light.diffuse.x, light.diffuse.y, light.diffuse.z);
glUniform3f(glGetUniformLocation(lightingShader.GetProgID(), (glslUniformName + ".specular").c_str()), light.specular.x, light.specular.y, light.specular.z);
// Load specific light attributes
LoadLightSpecific<LightType>(shaderId, light, glslUniformName); // ???
}
template <typename LightType>
void LoadLightSpecific(GLuint shaderId, const LightType& light, const std::string& glslUniformName);
The specializations for LoadLightSpecific is on a separate .cpp file which is irrelevant with my question.
My problem is in the line with the ???.
I am using LoadLightSpecific before I define it! I thought that this would give me a undeclared identifier (or something like that) compile error but no. It works normally.
Why is that happening? I feel like I am missing something obvious.
Update 23/11/2015
So, as people recommended in comments I used Wandbox to recreate the problem with minimal code. I ended up here. Apparently, the answer to my question seems to be:
"The code should not compile but somehow MSVC works his way around the problem"
It is not unusual with templates that when writing them, you assume something about the template arguments. i.e:
Template<class T>
class C
{
void foo() { T.bar(); }
};
Even though we dont know if T will actually have a method bar(), the compiler accepts it at the moment, because it is just a "template", not actual code. At the time when you instantiate a template, with some arguments, the compiler will check for the correctness of what you assumed, because now it has to generate code.
In the case of functions it is the same. The same logic must apply unless somebody finds an explicit statement about it in the standard, which I tried to find and didn't.
If we follow this logic, when you wrote the template of LoadLight, you assumed that there exists such a function called LoadLightSpecific<T>. In other words,
Why would T.bar() and bar<T>() be accepted in a class template, but not in a function template?
The templated function is not translated at the place of its templated definition, but when it is actually called (similar to the instantiation of a templated class) with some specific template argument. If at that place, all what is needed is available (LoadLightSpecific declared), then it will work fine.
However, I think that it is good practice to, as much as possible, have things declared at the place of the template definition. This will make it easier to track the dependencies.
For this particular code:
If there's a function template called LoadLightSpecific in scope at the point of definition, then this template definition is valid by itself. (It doesn't have to have that signature; even template<int> void LoadLightSpecific(); will do.)
The reason for this is that the compiler must know LoadLightSpecific is a template in order to parse the < as the start of a template argument list, rather than the less-than operator.
Since LoadLightSpecific<LightType>, if parsed as a template-id, is dependent on a template parameter, name lookup for LoadLightSpecific is postponed until instantiation. (Note that this does not mean instantiation will necessarily succeed: a declaration that is not in the template definition context can only be found in the instantiation context by ADL, not by normal unqualified lookup.)
In the more general case, the standard specifies what names are considered dependent on a template parameter and what aren't. Non-dependent names are looked up and bound at the point of template definition:
If a name does not depend on a template-parameter (as defined in
14.6.2), a declaration (or set of declarations) for that name shall be in scope at the point where the name appears in the template
definition; the name is bound to the declaration (or declarations)
found at that point and this binding is not affected by declarations
that are visible at the point of instantiation.
MSVC is well-known for its nonconformance in this area.

How does the compilation of templates work?

I'm reading a book about how templates work, and I'm having difficulty understanding this explanation of templates.
It says
When the compiler sees the definition of a template, it does not generate code. It generates code only when we instantiate a specific instance of the template. The fact that code is generated only when we use a template (and not when we define it) affects how we organize our source code and when errors are detected...To generate an instantiation, the compiler needs to have the code that defines a function template or class template member function. As a result, unlike non-template code, headers for templates typically include definitions as well as declarations.
What exactly does it mean by "generate code"? I don't understand what is different when you compile function templates or class templates compared to regular functions or classes.
The compiler generates the code for the specific types given in the template class instantiation.
If you have for instance a template class declaration as
template<typename T>
class Foo
{
public:
T& bar()
{
return subject;
}
private:
T subject;
};
as soon you have for example the following instantiations
Foo<int> fooInt;
Foo<double> fooDouble;
these will effectively generate the same linkable code as you would have defined classes like
class FooInt
{
public:
int& bar()
{
return subject;
}
private:
int subject;
}
and
class FooDouble
{
public:
double& bar()
{
return subject;
}
private:
double subject;
}
and instantiate the variables like
FooInt fooInt;
FooDouble fooDouble;
Regarding the point that template definitions (don't confuse with declarations regardless of templates) need to be seen with the header (included) files, it's pretty clear why:
The compiler can't generate this code without seeing the definition. It can refer to a matching instantiation that appeared first at linking stage though.
What does a non-template member function have that allows for it to
be defined outside of the header that a template function doesn't
have?
The declaration of a non-template class/member/function gives a predefined entry point for the linker. The definition can be drawn from a single implementation seen in a compiled object file (== .cpp == compilation unit).
In contrast the declaration of a templated class/member/function might be instantiated from arbitrary compilation units given the same or varying template parameters. The definition for these template parameters need's to be seen at least once. It can be either generic or specialized.
Note that you can specialize template implementations for particular types anyway (included with the header or at a specific compilation unit).
If you would provide a specialization for your template class in one of your compilation units, and don't use your template class with types other than specialized, that also should suffice for linking it all together.
I hope this sample helps clarifying what's the difference and efforts done from the compiler.
A template is a pattern for creating code. When the compiler sees the definition of a template it makes notes about that pattern. When it sees a use of that template it digs out its notes, figures out how to apply the pattern at the point where it's being used, and generates code according to the pattern.
What is the compiler suppose to do when it sees a template? Generate all the machine code for all possible data types - ints, doubles, float, strings, ... Could take a lot of time. Or just be a little lazy and generate the machine code for what it requires.
I guess the latter option is the better solution and gets the job done.
The main point here is that compiler does not treat a template definition until it meets a certain instance of the template. (Then it can proceed, I guess, like it have a usual class, which is a specific case of the template class, with fixed template parameters.)
The direct answer to your question is: Compiler generates machine code from users c++ code, I think this is wat is meant here by word "generate code".
The template declaration must be in header file because when compiler compiles some source, which use template it HAVE only header file (included in source with #include macro), but it NEED whole template definition. So logical conclusion is that template definition must be in header.
When you create a function and compile it, the compiler generates code for it. Many compilers will not generate code for static functions that are not used.
If you create a templated function and nothing uses the template (such as std::sort), the code for the function will not be generated.
Remember, templates are like stencils. The templates tell how to generate a class or function using the given template parameters. If the stencil is not used, nothing is generated.
Consider also that the compiler doesn't know how to implement or use the template until it sees all the template parameters resolved.
It won't straight away generate code. Only generates the class or template code when it comes across an instantiation of that template. That is, if you are actually creating an object of that template definition.
In essence, templates allow you abstract away from types. If you need two instantiations of the template class for example for an int and a double the compiler will literally create two of these classes for you when you need them. That is what makes templates so powerful.
Your C++ is read by the compiler and turned into assembly code, before being turned in machine code.
Templates are designed to allow generic programming. If your code doesn't use your template at all, the compiler won't generate the assembly code associated. The more data types you associate your template with in your program, the more assembly code it will generate.

Template function in non-template class - Division between H and CPP files

I was (and have been for a long time) under the impression that you had to fully define all template functions in your .h files to avoid multiple definition errors that occur due to the template compilation process (non C++11).
I was reading a co-worker's code, and he had a non-template class that had a template function declared in it, and he separated the function declaration from the function definition (declared in H, defined in CPP). It compiles and works fine to my surprise.
Is there a difference between how a template function in a non template class is compiled, and how a function in a template class is compiled? Can someone explain what that difference is or where I might be confused?
The interesting bit is how and when the template gets instantiated. If the instantiations can be found at link time, the template definition doesn't need to be visible in the header file.
Sometimes, explicit instantiations are cause like this:
header :
struct X {
// function template _declaration_
template <typename T> void test(const T&);
};
cpp:
#include "X.h"
// function template _definition_:
template <typename T>
void X::test(const T&)
{
}
// explicit function template _instantiation(s)_:
template X::test<int>(const int&);
template X::test<std::string>(const std::string&);
Using this sample, linking will succeed unless uninstantiated definitions of the template are used in other translation units
There is no difference between function templates defined in namespace or in class scope. It also doesn't matter whether is inside class template or not. What matter is that at some point in the project any used function template (whether member or non-member) is instantiated. Let's go over the different situations:
Unused function templates don't need to be instantiated and thus their implementation doesn't need to be visible to compiler at any point in time. This sounds boring but is important e.g. when using SFINAE approaches where class or function templates are declared but not defined.
Any function template which is defined where it is used will be instantiated by the compiler in a form which allows multiple definitions across different translation units: only one of the instantiations is retained. It is important that all the different definitions are merged because you could detect differences if you took the address of a function template or used a state variable inside the function template: there shall be only one of these for each instantiation.
The most interesting setup is where the definition of the function template is not seen when the function template is used: in this case the compiler cannot instantiate it. When the compiler sees a definition of the function template in a different translation unit it wouldn't know which template arguments to instantiate! A Catch 22? Well, you can always explicitly instantiate a template once. Having multiple explicit instantiations would create multiply defined symbols.
These are roughly the important options. There are often good reasons that you don't want to have the definition of a function template in the header. For example, you don't necessarily want to drag in dependencies you wouldn't have otherwise. Putting the definition of the function template somewhere else and explicitly instantiating it is a good thing. Also, you might want to reduce the compile time e.g. by avoiding to instantiate essentially the entire I/O stream and locale library in every translation unit using the stream. In C++ 2011 extern templates were introduced which allow the declaration that a particular template (either function or class template) is defined externally once for the entire program and there isn't any need to instantiate it in every header using particularly common template arguments.
For a longer version of what I just said, including examples have a look at a blog post
I wrote last weekend on this topic.