Compile time vs runtime?

D

desktop

I have read that using templates makes types know at compile time and
using inheritance the types are first decided at runtime. The use of
pointers and casts also indicates that the types will first be know at
runtime.

But is there some strict definitions that defines runtime code and
compile time code that can be used in general?
 
?

=?iso-8859-1?q?Erik_Wikstr=F6m?=

I have read that using templates makes types know at compile time and
using inheritance the types are first decided at runtime. The use of
pointers and casts also indicates that the types will first be know at
runtime.

Don't know if this answers your question or not; the idea behind
templates it that you at compile-time knows all the types that can be
used, and then generate code for each of those types. That's why it's
called templates, since it's not the code you write that gets executed
since it's just a template used by the compiler to generate the code
that will be executed.
But is there some strict definitions that defines runtime code and
compile time code that can be used in general?

Compile-time is compile-time, meaning that all the magic takes place
before the application is compiled, which is about as typesafe as you
can get. With runtime the magic happens when needed and have not been
fully checked at compilation. This means that for compile-time
polymorphism you need to know most if not everything about the types
at compile-time, which is why you can't have containers that can be
used with any type as compiled code, but have to distribute the source
(see the standard containers).
 
D

desktop

Erik said:
Don't know if this answers your question or not; the idea behind
templates it that you at compile-time knows all the types that can be
used, and then generate code for each of those types. That's why it's
called templates, since it's not the code you write that gets executed
since it's just a template used by the compiler to generate the code
that will be executed.


Compile-time is compile-time, meaning that all the magic takes place
before the application is compiled, which is about as typesafe as you
can get. With runtime the magic happens when needed and have not been
fully checked at compilation. This means that for compile-time
polymorphism you need to know most if not everything about the types
at compile-time, which is why you can't have containers that can be
used with any type as compiled code, but have to distribute the source
(see the standard containers).


Is not possible to have a heterogeneous container at compile-time? I
have read about a method that uses the heap and makes sure that each
element in the container is allocated:

http://gethelp.devx.com/techtips/cpp_pro/10min/10min0900.asp

Another technique deals with simulating dynamic polymorphism (deriving
classes from a base class) with the "The Curiously Recurring Template
Pattern": CRTP:

http://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern

Would either of these method not help me to generate a container with
different types at compile-time?
 
?

=?iso-8859-1?q?Erik_Wikstr=F6m?=

Is not possible to have a heterogeneous container at compile-time? I
have read about a method that uses the heap and makes sure that each
element in the container is allocated:

http://gethelp.devx.com/techtips/cpp_pro/10min/10min0900.asp

In this article they store pointers to a base-class, so the elements
stored are all of the same type. However when you dereference them you
can utilize runtime polymorphism.
Another technique deals with simulating dynamic polymorphism (deriving
classes from a base class) with the "The Curiously Recurring Template
Pattern": CRTP:

http://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern

Would either of these method not help me to generate a container with
different types at compile-time?

No, read this entry in the FAQ for a description about how to create
heterogeneous container using templates, notice that the first method
is the same as in the first article you posted.
http://www.parashift.com/c++-faq-lite/containers.html#faq-34.4
 
D

desktop

Erik said:
In this article they store pointers to a base-class, so the elements
stored are all of the same type. However when you dereference them you
can utilize runtime polymorphism.


No, read this entry in the FAQ for a description about how to create
heterogeneous container using templates, notice that the first method
is the same as in the first article you posted.
http://www.parashift.com/c++-faq-lite/containers.html#faq-34.4

Thanks for the link I will look into the methods described.

I thought that with dynamic polymorphism heterogeneous containers was
not an issue, at least that is what my book says (C++ Templates: The
complete Guide page 238).

Heterogeneous containers first becomes a problem when dealing with
static polymorphism. But as it says on the wiki page in regard to CRTP:

"This technique achieves a similar effect to the use of virtual
functions, without the costs (and some flexibility) of dynamic polymorphism"


So I still can't see why CRTP does not provide at pattern for
heterogeneous containers with static polymorphism.

With CRTP you can create a base class "Base" and then a number of
derived classes and get the same functionality as with virtual functions
but without the runtime cost. So making a container with this base
class should in theory give me a heterogeneous container.

If CRTP cannot be used to make a heterogeneous container what kind of
purpose does it have?
 
Z

Zeppe

desktop said:
Would either of these method not help me to generate a container with
different types at compile-time?

Is not possible to generate a container with different types at
compile-time. Everything is at compile-time is static, frozen.
Obviously, a container is not frozen, that is, you don't know all the
types of all the elements of an heterogeneus container before actually
launching the program.

Regards,

Zeppe
 
N

Noah Roberts

desktop said:
I have read that using templates makes types know at compile time and
using inheritance the types are first decided at runtime. The use of
pointers and casts also indicates that the types will first be know at
runtime.

But is there some strict definitions that defines runtime code and
compile time code that can be used in general?

One good rule that is quite important is that name and type resolution
is "static" (compile time). I think you can pretty much use this rule
to derive the rest.

The only remotely exception to this rule is RTTI, which is not complete
enough to truly resolve a type. You can use dynamic casting to be sure
you are casting to a compatible type but you can't ever find the real
type of your object.

Everything else is done through static resolution through the variable
that is being manipulated followed by some pointer dereferencing.
 
N

Noah Roberts

Zeppe said:
Is not possible to generate a container with different types at
compile-time. Everything is at compile-time is static, frozen.
Obviously, a container is not frozen, that is, you don't know all the
types of all the elements of an heterogeneus container before actually
launching the program.

True, but you can make a container that contains objects that
heterogeneously wrap any other object.
 
Z

Zeppe

Noah said:
True, but you can make a container that contains objects that
heterogeneously wrap any other object.

Yes, but the type of the wrapped object is to be determined at run-time.

Regards,

Zeppe
 
D

desktop

Zeppe said:
Yes, but the type of the wrapped object is to be determined at run-time.

Regards,

Zeppe


Just to be sure: If one writes runtime code it is possible to make a
heterogeneous container. As an example I have the following:


class Base {
....
};

class BaseOne : public Base {
....
};

class BaseTwo : public Base {
....
};


I can now make:

std::vector<Base*> bases;

Since I am using a pointer to a Base object I can still add BaseOne and
BaseTwo to the container since since they have Base as their base class.

At runtime it will be decided which types are in the container.

So as long as you write runtime code its possible to make a
heterogeneous container.

Its only when one wants compile time code that its impossible to have a
heterogeneous container.



the type of the object will be





If I have a few classes that inherits from Vector I can make:

std::vector<>
 
N

Noah Roberts

desktop said:
Just to be sure: If one writes runtime code it is possible to make a
heterogeneous container. As an example I have the following:


class Base {
...
};

class BaseOne : public Base {
...
};

class BaseTwo : public Base {
...
};


I can now make:

std::vector<Base*> bases;

Since I am using a pointer to a Base object I can still add BaseOne and
BaseTwo to the container since since they have Base as their base class.

At runtime it will be decided which types are in the container.

Nope. What type is in the container is decided at compile time. That
type is pointer to Base.
 
D

desktop

Noah said:
Nope. What type is in the container is decided at compile time. That
type is pointer to Base.

Ok but the container is still heterogeneous since it can both contain
BaseOne and BaseTwo pointers even though is created for type Base pointer.
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

Ok but the container is still heterogeneous since it can both contain
BaseOne and BaseTwo pointers even though is created for type Base pointer.

Not really, a true heterogeneous container can contain objects of
different types, in this case there is only one type and that is a
pointer to Base. What makes this work close enough as a heterogeneous
container is the fact that the pointer to Base does not have to point to
an object of type Base, it might just as well point to an object of a
type derived from Base (BaseOne or BaseTwo).

If the type Base have any virtual methods and you call any of them
through dereferencing a pointer to Base (or a reference) then dynamic
binding comes into play and makes sure that the correct method in the
derived class that the pointer actually points to is called.

However if you in one of the derived types adds a method (that did not
exist in Base) and try to call it using a pointer to Base it will not
work since Base does not have that method.
 
J

Juha Nieminen

desktop said:
I have read that using templates makes types know at compile time and
using inheritance the types are first decided at runtime. The use of
pointers and casts also indicates that the types will first be know at
runtime.

I think you have a slight confusion here.

Inheritance per se does not generate runtime type resolving code.
Only if the classes have virtual functions and they are called the
functions which actually get called is resolved at runtime.
Non-virtual functions can be resolved at compile-time (well, at
linking stage, more precisely).

Pointers and casts in general do not generate runtime code. The
only cast which does is a dynamic upcast. (There might also be some
multiple inheritance cases where downcasting actually changes the
value of the pointer, but by how much this is changed can, afaik,
be resolved at compile time.)
 
D

desktop

Juha said:
I think you have a slight confusion here.

Inheritance per se does not generate runtime type resolving code.
Only if the classes have virtual functions and they are called the
functions which actually get called is resolved at runtime.
Non-virtual functions can be resolved at compile-time (well, at
linking stage, more precisely).

Pointers and casts in general do not generate runtime code. The
only cast which does is a dynamic upcast. (There might also be some
multiple inheritance cases where downcasting actually changes the
value of the pointer, but by how much this is changed can, afaik,
be resolved at compile time.)

On this page:

http://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern

and alternative to paying the price for virtual functions at runtime is
the pattern CRTP. Would this pattern not give my the same functionality
but just at compile time?
 
T

Thomas J. Gritzan

desktop said:
On this page:

http://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern

and alternative to paying the price for virtual functions at runtime is
the pattern CRTP. Would this pattern not give my the same functionality
but just at compile time?

No. With the CRTP, you don't have a common base class where you can call
member functions:

template <typename Derived>
class base<Derived> {};

class derived1 : public base<derived1> {};
class derived2 : public base<derived2> {};

base<derived1> and base<derived2> are different types, so you can't put
them in the same container and you can't have a pointer of base* that can
hold both types.
 
O

Ole Nielsby

Juha said:
Pointers and casts in general do not generate runtime code.
The only cast which does is a dynamic upcast. (There might
also be some multiple inheritance cases where downcasting
actually changes the value of the pointer,

You don't need multiple-inheritance to screw things up:

#include <iostream>
class a{char c;};
class b: public a{virtual void whatever(){};};
int main(int argc, char* argv[]) {
b x;
std::cout << &x << " " << (a*)&x << "\n";
return 0;}
but by how much this is changed can, afaik,
be resolved at compile time.)

Except when downcasting to a virtual base class:

#include <iostream>
class a{char c;};
class b: public virtual a {};
class c1: public b {};
class c2: public b {};
class d: public c1, public c2 {};
int main(int argc, char* argv[]) {
d x;
b *b1 = (c1*)&x;
b *b2 = (c2*)&x;
std::cout << b1 << " " << (a*)b1 << "\n";
std::cout << b2 << " " << (a*)b2 << "\n";
return 0;}

Here, b1 and b2 point to different objects sharing the same a, so the
offsets differ and have be stored in the vtable.
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top