Why class member functions are not created only when they are needed?

I

Ioannis Vranos

AFAIK most (all?) compilers create instances of all member functions of a class even if some of them are not
used, an instances of all regular functions even if some of them are not used.

At the same time, in the case of template functions, only instances that are used are created.


Why a compiler can not create instances *only* of the regular functions, and of the member functions of a
class that are used?



Thanks.


--
Ioannis A. Vranos

C95 / C++03 Developer

http://www.cpp-software.net
 
N

Neelesh

AFAIK most (all?) compilers create instances of all member functions of a class even if some of them are not
used, an instances of all regular functions even if some of them are not used.

At the same time, in the case of template functions, only instances that are used are created.

Why a compiler can not create instances *only* of the regular functions, and of the member functions of a
class that are used?

Thanks.

IMHO The term "instance creation" doesnot make much sense for global
and member functions. There is no code that compiler needs to
"generate" for these functions. Further, the compiler doesnot know if
these functions would be needed in other translational units. Hence it
cannot just "ignore them" while generating object code. As far as
template functions are concerned, the compiler doesnot instantate the
cases that are not used according to 14.7.1p9: "An implementation
shall not implicitly instantiate a function template, a member
template, a nonvirtual member function, a member class or a static
data member of a class template that does not require instantiation."
 
J

Juha Nieminen

Ioannis said:
AFAIK most (all?) compilers create instances of all member functions of
a class even if some of them are not
used, an instances of all regular functions even if some of them are not
used.

Because when the compiler is generating the object files it has no way
of knowing which functions are really used and which aren't.

Usually the linker could remove unused functions from the final
executable. However, it might be that even the linker cannot do that
because it has no way of knowing whether some dynamically loadable
library will need those functions. (After all, loading dynamically
loadable libraries entails making some kind of runtime linking.)

At the same time, in the case of template functions, only instances that
are used are created.

That's because the compiler can see what is used and what isn't. This
is even so with export templates. Template functions cannot be linked
against at runtime.
 
I

Ioannis Vranos

Juha said:
Because when the compiler is generating the object files it has no way
of knowing which functions are really used and which aren't.

Usually the linker could remove unused functions from the final
executable. However, it might be that even the linker cannot do that
because it has no way of knowing whether some dynamically loadable
library will need those functions. (After all, loading dynamically
loadable libraries entails making some kind of runtime linking.)



That's because the compiler can see what is used and what isn't. This
is even so with export templates. Template functions cannot be linked
against at runtime.


However AFAIK, when a type from a template class is created, all of its member functions are created too in
most compilers.


Why does this happen?


--
Ioannis A. Vranos

C95 / C++03 Developer

http://www.cpp-software.net
 
I

Ian Collins

Ioannis said:
However AFAIK, when a type from a template class is created, all of its
member functions are created too in most compilers.

Are they?
 
J

James Kanze

Because when the compiler is generating the object files it
has no way of knowing which functions are really used and
which aren't.
Usually the linker could remove unused functions from the
final executable. However, it might be that even the linker
cannot do that because it has no way of knowing whether some
dynamically loadable library will need those functions. (After
all, loading dynamically loadable libraries entails making
some kind of runtime linking.)

Normally, unless you know up front that all of the functions
will be used, each non-virtual member function will be in a
separate source file, resulting in a separate object file, with
all of the object files in a library, so that the linker will
only incorporate the functions actually used.

And as you say, once dynamic linking is involved, the issues
become more complicated.
That's because the compiler can see what is used and what
isn't. This is even so with export templates. Template
functions cannot be linked against at runtime.

Let's get the vocabulary straight, first. In more recent
versions of the C++ standard, there are no "template functions",
because the term is ambiguous: do you mean function templates,
or instantiations of a function template? If the first,
template functions can't be linked against at runtime, because
they aren't code, and don't generate any code. If the second,
there's no problem linking against them at runtime, provided
they have been instantiated correctly.
 
J

Juha Nieminen

Ioannis said:
However AFAIK, when a type from a template class is created, all of its
member functions are created too in most compilers.

No, they aren't. If they were, that would break some programs. (In
fact, much of template metaprogramming is based on the fact that
template class member functions are instantiated only when needed.)

Some classes take advantage of this. For example, you could have a
wrapper class around some STL class like this:

template<typename Container>
class Wrapper
{
Container container;

public:
void foo()
{
container.push_front(something);
}
...
};


If Wrapper::foo() is never called, it will never be instantiated
either, and thus the requirement that Container must support
push_front() is never actualized. Thus it's possible to use something
like Wrapper<std::vector> as long as the foo() function is never called.
 
I

Ioannis Vranos

Juha said:
No, they aren't. If they were, that would break some programs. (In
fact, much of template metaprogramming is based on the fact that
template class member functions are instantiated only when needed.)

Some classes take advantage of this. For example, you could have a
wrapper class around some STL class like this:

template<typename Container>
class Wrapper
{
Container container;

public:
void foo()
{
container.push_front(something);
}
...
};


If Wrapper::foo() is never called, it will never be instantiated
either, and thus the requirement that Container must support
push_front() is never actualized. Thus it's possible to use something
like Wrapper<std::vector> as long as the foo() function is never called.


A wrapper for vector, for non-instantiation, is not needed , since vector is a template itself.


However if we want to be as much space efficient as possible, shouldn't we always declare/define our classes
and functions as templates?



Perhaps an extension would be practical:


// <class> means this class does not take any argument types, or in other words is stand-alone.
template<class>
class SomeClass
{
// ...
};



int main()
{
SomeClass obj;
}



The equivalent today can be done in the style:


template<class T>
class SomeClass
{
// ...
};



int main()
{
// "int" is not used.
SomeClass<int> obj;
}




--
Ioannis A. Vranos

C95 / C++03 Developer

http://www.cpp-software.net
 
J

Juha Nieminen

Ioannis said:
A wrapper for vector, for non-instantiation, is not needed , since
vector is a template itself.

The objective of the wrapper was not to avoid member function
instantiation. It was just an example of conditional instantiation being
useful. The wrapper could be, for example, some kind of queue data
structure which you can use just fine with a std::vector as long as you
don't call anything which requires push_front() or pop_front(). The
beauty of the templated wrapper is that even though its functions call
those functions of the container, they will not cause any error if they
are never called.
 
I

Ioannis Vranos

Corrected:


Ioannis said:
A wrapper for vector, for non-instantiation, is not needed , since
vector is a template itself.


However if we want to be as much space efficient as possible, shouldn't
we always declare/define our classes and functions as templates?



Perhaps an extension would be practical:
==> // said:
other words is stand-alone.
template<class>
class SomeClass
{
// ...
};



int main()
{
SomeClass obj;
}


The equivalent today can be done in the style:


// "int" is not used.
template<class T= int>
class SomeClass
{
// ...
};



int main()
{
SomeClass<> obj;
}



--
Ioannis A. Vranos

C95 / C++03 Developer

http://www.cpp-software.net
 
J

James Kanze

Juha Nieminen wrote:
However if we want to be as much space efficient as possible,
shouldn't we always declare/define our classes and functions
as templates?

Why? All virtual functions are considered "used", and will be
instantiated anyway. And if you put each non-virtual function
in a separate file (which should be standard procedure for
anyone writing a general purpose library), then the final
executable will only contain those which are actually used.

(For application level code, as opposed to libraries, this is a
non-issue. If a function isn't used, you don't write it.)
 
I

Ioannis Vranos

James said:
Why? All virtual functions are considered "used", and will be
instantiated anyway. And if you put each non-virtual function
in a separate file (which should be standard procedure for
anyone writing a general purpose library), then the final
executable will only contain those which are actually used.

(For application level code, as opposed to libraries, this is a
non-issue. If a function isn't used, you don't write it.)


I am talking about non-virtual functions.


What I am saying is, if we want to avoid member function instantiation when a "non-template" class object is
created, we can still define the class as a template.


--
Ioannis A. Vranos

C95 / C++03 Developer

http://www.cpp-software.net
 
B

Bo Persson

Ioannis said:
I am talking about non-virtual functions.


What I am saying is, if we want to avoid member function
instantiation when a "non-template" class object is created, we can
still define the class as a template.

I don't think it is a problem in practice, if you just follow James'
advice - don't write functions that you don't need.

Solved! :)


Bo Persson
 
I

Ioannis Vranos

Richard said:
Same answer. If you don't need them, why write them?


So let's assume we have a concrete type (stand alone class), e.g. a complex class. And we don't use all its
member functions in a program, why should we have them imposed to us?

Instead we can write such a class, as a template class with its type argument not used. An extension of the style:


template <class>
class SomeClass;


and

template<typename>
class SomeClass;


to denote a template class without type arguments, could be useful.



--
Ioannis A. Vranos

C95 / C++03 Developer

http://www.cpp-software.net
 
J

James Kanze

I am talking about non-virtual functions.
What I am saying is, if we want to avoid member function
instantiation when a "non-template" class object is created,
we can still define the class as a template.

And I answered that: if you don't want the function
instantiated, don't write it. In the case of a class template,
the function may be needed for one instantiation, but not for
others, so you have to write it. In the case of a non-template
class, there's only one instantiation, which either needs the
function, or doesn't. If it doesn't need it, you don't write
it.
 
I

Ioannis Vranos

James said:
And I answered that: if you don't want the function
instantiated, don't write it. In the case of a class template,
the function may be needed for one instantiation, but not for
others, so you have to write it. In the case of a non-template
class, there's only one instantiation, which either needs the
function, or doesn't. If it doesn't need it, you don't write
it.


I do not think what you are saying is the answer for maximum space efficiency when classes are used.


Let's take as an example a C++ framework, Qt.

You may use a QComboBox, but you do not need all its member functions in a usual application. The same applies
for a QButton, QTcpSocket, and the other classes.



--
Ioannis A. Vranos

C95 / C++03 Developer

http://www.cpp-software.net
 
B

Bart van Ingen Schenau

So let's assume we have a concrete type (stand alone class), e.g. a complex class. And we don't use all its
member functions in a program, why should we have them imposed to us?

But what is the problem you are trying to solve here?
If you are writing the class, those functions are not imposed on you,
because you don't have to write them.
If you are using an existing class, the worst case is that your linker
is not smart enough to throw out a few bytes of unused code. So what.
For platforms where memory comes at a premium, the linkers are already
smart enough not to burden you with unused code, and for other
platforms you will probably not notice the difference.

I think you are forgetting the reason why memberfunctions of a
template are treated special: It is not an optimisation issue, but a
correctness one.
For non-template classes, all member functions must always be
syntactically and semantically correct, so there is no reason not to
compile them.
For template classes, it can be that for a particular specialisation
not all member functions are syntactically or semantically correct. If
the the (incorrect) member is not used, you don't want a complaint
from the compiler that the member is incorrect.
Instead we can write such a class, as a template class with its type argument not used. An extension of the style:

template <class>
class SomeClass;

and

template<typename>
class SomeClass;

to denote a template class without type arguments, could be useful.

I don't see the use.

Bart v Ingen Schenau
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,007
Messages
2,570,266
Members
46,863
Latest member
montyonthebonty

Latest Threads

Top