奇怪的无符号数相减 —— 引出的RTTI, typeid(type).name

2011-03-29 wcdj

 

// 测试代码 #include <stdio.h> int main() { unsigned short us1= 2, us2 = 3; int i1 = (us1 - us2 > 0); unsigned int ui1 = 2, ui2 = 3; int i2 = (ui1 - ui2 > 0); printf("%d,%d/n", i1, i2);// 0 1 return 0; }

 

解释如下:
unsigned short 会类型提升为 int,所以 us1-us2 不是一个无符号的数,而是一个 int 类型的数,即有符号的数。可以用下面代码验证:

#include <iostream> using namespace std; int main(int argc, char* argv[]) { unsigned short us1 = 2, us2 = 3; cout << (us1 - us2) << endl; // 输出-1 cout << typeid((us1 - us2)).name() << endl; // 类型提升为int int i1 = ((us1 - us2) > 0); cout << i1 << endl;// 0 unsigned int ui1 = 2, ui2 = 3; cout << (ui1 - ui2) << endl; // 输出一个很大的int 4294967295 cout << typeid((ui1 - ui2)).name() << endl; // 类型仍然是unsigned int int i2 = ((ui1 - ui2) > 0); cout << i2 << endl;// 1 return 0; }

 


知识补充:


RTTIRun-Time Type Identification运行时类型识别),它使程序能够获取由基指针或引用所指向的对象的实际派生类型,即允许“用指向基类的指针或引用来操作对象”的程序能够获取到“这些指针或引用所指对象”的实际派生类型。在C++中,为了支持RTTI提供了两个操作符:dynamic_casttypeid

typeid是C++的关键字之一,等同于sizeof这类的操作符。typeid操作符的返回结果是名为type_info的标准库类型的对象的引用(在头文件typeinfo中定义),它的表达式有两种形式:(1) typeid(type)   (2) typeid(expr)

注意:
如果表达式的类型是类类型且至少包含有一个虚函数,则typeid操作符返回表达式的动态类型,需要在运行时计算;否则,typeid操作符返回表达式的静态类型,在编译时就可以计算。

ISO C++标准并没有确切定义type_info,它的确切定义编译器相关的,但是标准却规定了其实现必需提供如下四种操作
(1) t1 == t2  如果两个对象t1和t2类型相同,则返回true;否则返回false
(2) t1 != t2  如果两个对象t1和t2类型不同,则返回true;否则返回false
(3) t.name()  返回类型的C-style字符串,类型名字用系统相关的方法产生
(4) t1.before(t2)  返回指出t1是否出现在t2之前的bool值

注意:
type_info的name成员函数返回C-style的字符串,用来表示相应的类型名,但务必注意这个返回的类型名与程序中使用的相应类型名并不一定一致(往往如此),这具体由编译器的实现所决定的,标准只要求实现为每个类型返回唯一的字符串。


参考:
http://www.cppblog.com/smagle/archive/2010/05/14/115286.html
http://topic.csdn.net/u/20110328/18/566db861-e4ac-42a6-82aa-10eb41d0c547.html

 

你可能感兴趣的:(c,UI,测试,编译器,2010)