2

I have read other questions like 1347691 and know that what dynamic and static types are.

However, I am curious why the dynamic type is not known until runtime. After all, we human beings can decide the dynamic type by looking through the code. Why can't the compiler do that?

Actually we can use typeid to decide the so-called run-time type. Programming/RTTI.

So why in the book "C++ primer 5th", the author still says

dynamic type is not known until runtime

Community
  • 1
  • 1
Casualet
  • 295
  • 3
  • 12
  • 5
    Your code might be used with code, which will be written tomorrow. Neither the compiler nor the human can decide the dynamic type of a type which is invented tomorrow. – Micha Wiedenmann Jan 04 '17 at 08:56
  • for pointers you can use `dynamic_cast` and check if it worked by comparing the result to `nullptr` – JKreiser Jan 04 '17 at 08:59
  • 1
    `After all, we human beings can decide the dynamic type by look through the code` - have you ever seen a .SO/.DLL or .LIB that you link to your project and that returns you some objects? I wish you luck reading through it with standard human eyes with no disassembler. In case you now want to reply that even a SO/DLL or LIB all have a source code that can be read - yes sure, but when **linking** your code with them, tools link your code in binary form with other binary files, not source text. It's a bit late now for checking for type casting compliance. – quetzalcoatl Jan 04 '17 at 09:12
  • 2
    Btw. many compilers do "devirtualization" during the LTO process, in the cases where it can be done with less effort. Also profile-guided optimizations can improve the performance significantly by partial devirtualization based on the profiling statistics. – EmDroid Jan 04 '17 at 09:56

2 Answers2

14
Shape* shape = nullptr;

int userinput = 0;

std::cin >> userinput;    

if(userinput == 17)
{
  shape = new Circle();
}
else
{
  shape = new Square();
}

So can you tell me what type shape is, from looking at the code at compile time?

nvoigt
  • 75,013
  • 26
  • 93
  • 142
  • 2
    (pun) Sure, it's a `Square` or `Circle`. (/pun) – quetzalcoatl Jan 04 '17 at 09:02
  • I am 99.99999995343387126922607421875% sure it's a square :) Really great example tho. – Tomasz Plaskota Jan 04 '17 at 09:02
  • It's 100% not square (c++ is case sensitive) ;-) – Matthias Jan 04 '17 at 09:04
  • Thank you for this example. So if the dynamic type does not depend on inputs from human or files or other sources, Then the dynamic type can be decided at run-time ? Is that right? – Casualet Jan 04 '17 at 09:10
  • @Casualet: runtime? are you sure you didnt misspell it? it can *always* be decided at runtime.. – quetzalcoatl Jan 04 '17 at 09:13
  • @Casualet In theory yes. In practice, you will not find a single program worth looking at that does not make decisions based on external data at runtime, either user input, or data from a file or database. – nvoigt Jan 04 '17 at 09:14
  • @Casualet And if the shape in the example will *always* be a circle, then just write `Circle c;` instead of the code above and don't use the dynamic system at all. – nvoigt Jan 04 '17 at 09:23
  • 2
    In various simple cases yes, but in general, even without external input, it is equivalent to the **halting problem** (will the loop/program ever stop?), which is NP-hard. So it might be decidable, but it might as well take the compiler few (hundred millions) years to decide. I guess you wouldn't like to wait for that? :) – EmDroid Jan 04 '17 at 09:42
2

Why is dynamic type not known until runtime in C++?

Well, that is pretty much the definition of a dynamic type. If the type were known at compile time, then it would be no different from the definition of static type.

Actually we can use typeid to decide the so-called run-time type.

Which is evaluated at runtime.

After all, we human beings can decide the dynamic type by looking through the code. Why can't the compiler do that?

Us humans are notoriously bad at considering all past, current and future states that the program might encounter. It is easy to mistakenly assume the runtime type of a referenced object. A compiler cannot afford such mistakes.

However, there are cases where it is indeed possible to prove at compile- (or perhaps at link-) time the dynamic type of an object. If the compiler can prove the dynamic type before runtime, then it is free to optimize the code as if the type was static. The compiler may not change observable behaviour based on this proof, but it may optimize away virtual function calls and even expand the function calls inline. This is allowed by the as-if rule, and the optimization is known as devirtualization. A trivial example:

Derived d;
Base b* = &d;
b->virtual_function();

Here, the dynamic type of *b is, and always will be Derived, and it is easy to prove. The virtual dispatch can be replaced with a direct call to Derived::virtual_function.

eerorika
  • 232,697
  • 12
  • 197
  • 326