我被赋予了将Windows程序移植到OS X的任务。最初是用C ++编写的,我很享受它因为我不经常使用C语言系列,并且喜欢使用Objective端口中的C ++。
然而,Windows源代码做了一些奇怪的事情,我想知道它是否是标准做法。我们在Windows和OS X上使用的API期望一个特定的对象方法传递一个unsigned short。原始Windows开发人员创建了以下函数来计算此值:
static unsigned short hashcode ( const char* value ) {
int h = 0 ;
unsigned long length = strlen ( value ) ;
for ( int i = 0 ; i < length ; i++ ) {
h = ( 31 * h ) + value[i] ;
}
return h ;
}
注意,当函数返回unsigned short
时,它返回的变量被声明为int
。我检查了文档,OS X和Windows都将unsigned short
定义为2个字节,int
定义为4个。
传递给此函数的值,如果不考虑数据类型,则会导致函数返回非常大的数字,在某些情况下返回数十位数。在一个案例中,我用不太严格的类型的另一种语言复制算法,我的值为2081357292912430390912
。当我在命令行实用程序中包含上述函数时,相同的字符串返回值40576
,我猜是因为这是较长值的截断版本。
所以我有两个问题。首先,为什么,如果hashcode
被声明为返回unsigned short
并且它实际上正在返回并且int
不是编译器抱怨的话?首先不是严格的数据类型声明是什么?确保函数和方法接收并返回预期的数据类型?
第二,这种截断是一种标准做法吗?对我来说这似乎很奇怪,首先是利用隐式转换,但也没有评论向某人发出正在发生的事情(而且我无法访问原始开发人员的问题)。既然它没有被评论为“特殊”,也许它只是C / C ++中的标准习语?
答案 0 :(得分:2)
首先,为什么,如果声明hashcode返回unsigned short并且它实际上是返回而int并不是编译器抱怨?
因为可以隐式执行从int
到unsigned short
的转换
首先,这不是严格的数据类型声明吗?确保函数和方法接收并返回预期的数据类型?
是。而这正是这里发生的事情。声明为返回unsigned short
的函数返回unsigned short
,这是隐式转换的结果。
第二,这种截断是一种标准做法吗?
是
在使用强制转换的代码中没有明确说明它的一个很好的理由是C ++有一组可以隐式执行的转换,以及一组可以显式执行的转换。后一组包括一些有潜在危险的转换,例如指针和整数之间的转换。利用隐式转换,除非需要显式强制转换,否则可防止意外执行其中一次危险转换。
我确实看到了这个实现的潜在问题,但它与您的问题无关。我认为最好不要详细说明,只是不要误解我的答案作为对此功能的认可。
答案 1 :(得分:1)
我会继续假设你的意思是隐式转换而不是自动转换。根据我的经验,这种行为通常依赖于许多语言,包括C ++。要回答第一个问题,只要在分配的类型和分配的类型之间存在转换序列,这就不会导致编译器错误。
通常情况下,人们会在没有明确写== 0
或!= 0
的情况下传入整数。
示例:
int count = 10;
while (--count); // runs 10 times
int test = 0;
if (test); // evaluates to false
test = 1;
if (test); // evaluates to true
test = -1;
if (test); // evaluates to true
以下是有关隐式转化的一些文档http://en.cppreference.com/w/cpp/language/implicit_conversion