Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Addresses of identical function template instantiations across compilation units

Why does this work?

I see similar SO questions stating that it does, but could someone explain it in more detail? Particularly, is this behavior protected by a standard?

i.h

#ifndef I_H_
#define I_H_

typedef void (*FuncPtr)();

template<typename T>
void FuncTemplate() {}

class C {};

#endif

a.cc

#include "i.h"

FuncPtr a() {
  return &FuncTemplate<C>;
}

b.cc

#include "i.h"

FuncPtr b() {
  return &FuncTemplate<C>;
}

m.cc

#include <iostream>

#include "i.h"

FuncPtr a();
FuncPtr b();

int main() {
  std::cout << (a() == b() ? "equal" : "not equal") << std::endl;

  return 0;
}

Then

$ g++ -c -o a.o a.cc
$ g++ -c -o b.o b.cc
$ g++ -c -o m.o m.cc
$ g++ a.o b.o m.o -o prog
$ ./prog
equal

Tossing -Wall -Wextra -Werror -ansi onto all the g++ calls produces the same.

My (naive) understanding is that FuncTemplate is instantiated once in each of the a.o and b.o compilation units, and so the addresses should each point to one copy. How do these end up the same after all, and is this behavior portable or protected?

EDIT The shared library case:

$ g++ -shared -o liba.so a.cc
$ g++ -shared -o libb.so b.cc
$ g++ -c -o m.o m.cc
$ g++ -L. -la -lb m.o -o prog
$ ./prog
equal
like image 850
phs Avatar asked Oct 06 '11 03:10

phs


People also ask

What is function template explain this concept with the help of an example?

A template is a simple yet very powerful tool in C++. The simple idea is to pass data type as a parameter so that we don't need to write the same code for different data types. For example, a software company may need to sort() for different data types.

What is a template function?

Function templates are similar to class templates but define a family of functions. With function templates, you can specify a set of functions that are based on the same code but act on different types or classes. The following function template swaps two items: C++ Copy.

How many times are template classes compiled?

In general, yes, template classes are usually compiled every time they're encountered by the compiler.

How do I create a function template?

A function template starts with the keyword template followed by template parameter(s) inside <> which is followed by the function definition. In the above code, T is a template argument that accepts different data types ( int , float , etc.), and typename is a keyword.


2 Answers

This is covered under the one definition rule:

3.2 One definition rule [basic.def.odr]

Paragraph 5:

There can be more than one definition of a class type (Clause 9), enumeration type (7.2), inline function with external linkage (7.1.2), class template (Clause 14), non-static function template (14.5.6), static data member of a class template (14.5.1.3), member function of a class template (14.5.1.1), or template specialization for which some template parameters are not specified (14.7, 14.5.5) in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements. Given such an entity named D defined in more than one translation unit, then

There is a whole list of criteria that follow that have to be-adhered to or its undefined behavior. In the above these do hold. Then ...

If the definitions of D satisfy all these requirements, then the program shall behave as if there were a single definition of D.

So technically you can have a copy of the function in each translation unit.

It looks like the wording in the last phrase though makes it a requirement that they all behave the same. This means taking the address of any of these objects should result in the same address.

like image 52
Martin York Avatar answered Sep 24 '22 01:09

Martin York


This is guaranteed by the standard as it does not violate the one definition rule. In essence, if the declaration and definition of an inline function or template function is the same in multiple translation units, the program shall behave as though there is one definition of it, which extends to its address, when taken. See my answer to another question that involved static members of template classes.

As for the relevant section of the standard [basic.def.odr]:

... If the definitions of D satisfy all these requirements, then the program shall behave as if there were a single definition of D. If the definitions of D do not satisfy these requirements, then the behavior is undefined.

like image 35
MSN Avatar answered Sep 26 '22 01:09

MSN