info not a part of RTTI?
I had asked a question Do C++ POD types have RTTI? and someone told me in the comments:
POD types do have type_info, but don't have RTTI, and that's possible because type_info isn't always RTTI.
and it seems right as i could get the type_info
of a POD (non-polymorphic) type.
But while I compile this simple program:
#include <iostream>
struct X
{
int a;
};
int main()
{
using namespace std;
std::cout << typeid(X) << std::endl;
return 0;
}
with flag -fno-rtti
of GCC:
$ g++ -fno-rtti main.cpp && ./main
It won't compile:
main.cpp: In function ‘int main()’:
main.cpp:12:26: error: cannot use typeid with -fno-rtti
std::cout << typeid(X) << std::endl;
^
Does that mean type_info
is a part of RTTI, or is it just a behavior of GCC?
Abstract
RTTI per se is not something really formally defined: C++ only says what typeid
and dynamic_cast
do, not how they're implemented. However, it is convenient indeed to group such kind of operations under a common name which is RTTI.
Notice an implementation is not required to strictly obtain this information at runtime ie
if ( typeid(int) == typeid(double) )
could also be determined during the program evaluation, much like std::is_same
. int
is undeniably non-polymorphic (it has no 'dynamic' type). cppreference even claims:
When applied to an expression of polymorphic type, evaluation of a typeid expression may involve runtime overhead (a virtual table lookup), otherwise typeid expression is resolved at compile time.
But it's to be taken cautiously.
Does that mean type_info is a part of RTTI, or is it just a behavior of GCC?
type_info
is a class. You may not construct any object of that type - you only can through typeid
.
-fno-rtti
disable RTTI under GCC: you can't use typeid
, and thereby neither can be type_info
. They're very close each other.
To conclude, the original quote is totally right:
POD types do have type_info
, but don't have RTTI, and that's possible because type_info isn't always RTTI.
The runtime information is available through typeid
. There is just nothing dynamic to consider (indeed, dynamic_cast
would make no sense).
There is no concept of "RTTI" in the standard. Instead, it's said in different words.
<typeinfo>
is referred to as "dynamic type identification" in [support.general]
[intro.object] says: "Some objects are polymorphic (10.3); the implementation generates information associated with each such object that makes it possible to determine that object's type during program execution"
[expr.dynamic.cast] talks about checks that happen at "run-time". All other uses of "runtime" in the standard refer to something else.
[expr.typeid] explains what typeid
does:
2 When typeid
is applied to a glvalue expression whose type is a polymorphic class type (10.3), the result refers to a std::type_info
object representing the type of the most derived object (1.8) (that is, the dynamic type) to which the glvalue refers. ...
The latter is typically referred to a "run-time" operation.
3 When typeid
is applied to an expression other than a glvalue of a polymorphic class type, the result refers to a std::type_info
object representing the static type of the expression. ... The expression is an unevaluated operand (Clause 5).
While the former can be seen as a "compile-time" operation.
Regardless, GCC doesn't really care and disables typeid
and dynamic_cast
altogether if you use the -fno-rtti
flag:
rtti.c:
if (! flag_rtti)
{
error ("cannot use typeid with -fno-rtti");
return false;
}
Could it disable typeid
for polymorphic types only? Sure. But we're going to go with occam's razor in that it's much easier developmentally-wise to prevent the use of typeid
altogether.
下一篇: 信息不是RTTI的一部分?