Does C ++ have any kind of reflection?

Consider the following example:

struct Nobody_Expects_The_Spanish_Inquisition{}; int main(){ throw Nobody_Expects_The_Spanish_Inquisition(); } 

The result is shown on Ideone :

end call after calling Nobody_Expects_The_Spanish_Inquisition 'instance

Similar output for Windows:

Unhandled exception in 0x760fb727 in Test.exe: Microsoft C ++ exception: Nobody_Expects_The_Spanish_Inquisition in memory location 0x001ffea3 ..

As you can see, the last assembly seems to contain the exception name already, or there is another way to get the name.

Can this be considered as some kind of reflection? Or does it depend on the compiler / OS if the exception name can actually be displayed?

+6
source share
5 answers

It depends on the compiler. Obviously, the compiler easily recognizes every throw and encodes the type of each thrown object into an executable file. But there is no requirement that they do this.

And, thinking about it, exceptions should be copied into a strange implementation-dependent space when they are thrown. Thus, it makes sense that the name of their type is available through this mechanism for the runtime of a particular compiler.

+7
source

No, this is not a reflection in any significant capacity, just debugging symbols.

+3
source

When the exception goes beyond main , std::terminate is called, which in turn calls the installed completion handler. If a completion handler is not installed in the program, the default completion handler is called. The only requirement for this default completion handler is that it calls std::abort . This means that the implementation can print a useful message before calling std::abort , which seems to be the case here.

While to display this error message it is enough to reflect or debug characters or RTTI, they are not needed: the implementation can use any black magic, regardless of depth.

+2
source

This program:

 #include <typeinfo> #include <iostream> struct Nobody_Expects_The_Spanish_Inquisition { }; namespace junk { struct I_didnt_expect_a_kind_of_spanish_inquisition : public Nobody_Expects_The_Spanish_Inquisition { }; } int main(int argc, const char *argv[]) { using ::std::type_info; using ::std::cout; Nobody_Expects_The_Spanish_Inquisition foo; junk::I_didnt_expect_a_kind_of_spanish_inquisition bar; const type_info &fooinfo = typeid(foo); const type_info &barinfo = typeid(bar); cout << "The type of foo is <" << fooinfo.name() << ">\n"; cout << "The type of bar is <" << barinfo.name() << ">\n"; return 0; } 

has this conclusion:

 $ ./foo The type of foo is <38Nobody_Expects_The_Spanish_Inquisition> The type of bar is <N4junk44I_didnt_expect_a_kind_of_spanish_inquisitionE> 

This is as good as for introspection in C ++. And that’s enough to accomplish what the default completion handler does.

Although, as others have pointed out, the default completion handler is allowed to achieve this goal, anyway, this works well, I would be surprised if he did not use the same mechanisms that are used to implement typeid to make this work.

Of course, the default completion handler can work by referring to a special area that the compiler creates whenever an exception is thrown that writes everything that the compiler knows about the type name in the place of its throw. As others have pointed out, the default completion handler is placed there by the compiler and is not bound by any rule code written by a C ++ programmer.

I have seen people write their own terminal handlers that process the call stack and look at the debugging symbols associated with each address to get facsimile information about the stack trace. This is the magic of the compiler and platform, and since the compiler knows exactly which compiler and which platform it uses, it can have a default completion handler that did the same on a supported platform.

Therefore, RTTI is not required to implement the function you are marking. But RTTI is a very rudimentary form of reflection and can be used to implement this function.

0
source

“Reflection” is performed using RTTI. Nothing unusual, just a type name.

-1
source

Source: https://habr.com/ru/post/890261/


All Articles