C ++开发人员通常会依赖隐式转换吗?

时间:2016-05-10 17:50:19

标签: c++ standards

我被赋予了将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 ++中的标准习语?

2 个答案:

答案 0 :(得分:2)

  

首先,为什么,如果声明hashcode返回unsigned short并且它实际上是返回而int并不是编译器抱怨?

因为可以隐式执行从intunsigned 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