C++ 开发人员通常依赖隐式转换吗?
Do C++ developers commonly count on implicit casting?
我接到了将 Windows 程序移植到 OS X 的任务。最初是用 C++ 编写的,我很喜欢它,因为我不经常使用 C 系列的语言,并且喜欢在端口中使用 Objective C++。
但是,Windows 源代码做了一些奇怪的事情,我想知道这是否是标准做法。我们在 Windows 和 OS X 上使用的 API 期望一个特定的对象方法被传递一个无符号的 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 ;
}
请注意,虽然函数 return 是 unsigned short
,但它所 return 的变量被声明为 int
。我检查了文档,OS X 和 Windows 都将 unsigned short
定义为 2 个字节,将 int
定义为 4.
传递给此函数的值,如果不考虑数据类型,会导致函数 returning 非常大的数字,在某些情况下为数十位。在一种情况下,我用另一种类型不太严格的语言复制了该算法,我得到了 2081357292912430390912
的值。当我在命令行实用程序中包装上述函数时,相同的字符串 returned 的值为 40576
,我猜是因为这是较长值的截断版本。
所以我有两个问题。首先,为什么如果 hashcode
被声明为 return 和 unsigned short
而它实际上是 returning 而 int
编译器不会抱怨?这难道不是严格数据类型声明的首要目的吗?确保函数和方法接收并 return 预期的数据类型?
其次,这种截断是一种标准做法吗?这对我来说似乎很奇怪,首先要利用隐式转换,但也没有任何评论可以告诉某人正在发生的事情(而且我无法访问原始开发人员来询问)。因为它没有被评论为 "special," 可能它只是 C/C++?
中的标准习语
我继续假设您指的是隐式转换而不是自动转换。根据我的经验,许多语言(包括 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
First of all, why, if hashcode is declared to return an unsigned short and it's in fact returning and int doesn't the compiler complain?
因为从int
到unsigned short
的转换可以隐式执行
Isn't that what strict data type declarations are for in the first place? To make sure that functions and methods receive and return the data types expected?
是的。这正是这里正在发生的事情。作为该隐式转换的结果,声明为返回 unsigned short
的函数是 返回 unsigned short
。
And second, is this truncation a standard practice?
是的。
它没有在带有强制转换的代码中显式显示的一个很好的原因是 C++ 有一组可以隐式执行的转换,以及一组更大的可以显式执行的转换。后一组包括一些潜在危险的转换,例如指针和整数之间的转换。除非需要显式强制转换,否则利用隐式转换可防止意外执行其中一种危险转换。
我确实看到此实现存在潜在问题,但它与您的问题无关。我觉得还是不细说为好,不要把我的回答误认为是对这个功能的认可
我接到了将 Windows 程序移植到 OS X 的任务。最初是用 C++ 编写的,我很喜欢它,因为我不经常使用 C 系列的语言,并且喜欢在端口中使用 Objective C++。
但是,Windows 源代码做了一些奇怪的事情,我想知道这是否是标准做法。我们在 Windows 和 OS X 上使用的 API 期望一个特定的对象方法被传递一个无符号的 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 ;
}
请注意,虽然函数 return 是 unsigned short
,但它所 return 的变量被声明为 int
。我检查了文档,OS X 和 Windows 都将 unsigned short
定义为 2 个字节,将 int
定义为 4.
传递给此函数的值,如果不考虑数据类型,会导致函数 returning 非常大的数字,在某些情况下为数十位。在一种情况下,我用另一种类型不太严格的语言复制了该算法,我得到了 2081357292912430390912
的值。当我在命令行实用程序中包装上述函数时,相同的字符串 returned 的值为 40576
,我猜是因为这是较长值的截断版本。
所以我有两个问题。首先,为什么如果 hashcode
被声明为 return 和 unsigned short
而它实际上是 returning 而 int
编译器不会抱怨?这难道不是严格数据类型声明的首要目的吗?确保函数和方法接收并 return 预期的数据类型?
其次,这种截断是一种标准做法吗?这对我来说似乎很奇怪,首先要利用隐式转换,但也没有任何评论可以告诉某人正在发生的事情(而且我无法访问原始开发人员来询问)。因为它没有被评论为 "special," 可能它只是 C/C++?
中的标准习语我继续假设您指的是隐式转换而不是自动转换。根据我的经验,许多语言(包括 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
First of all, why, if hashcode is declared to return an unsigned short and it's in fact returning and int doesn't the compiler complain?
因为从int
到unsigned short
的转换可以隐式执行
Isn't that what strict data type declarations are for in the first place? To make sure that functions and methods receive and return the data types expected?
是的。这正是这里正在发生的事情。作为该隐式转换的结果,声明为返回 unsigned short
的函数是 返回 unsigned short
。
And second, is this truncation a standard practice?
是的。
它没有在带有强制转换的代码中显式显示的一个很好的原因是 C++ 有一组可以隐式执行的转换,以及一组更大的可以显式执行的转换。后一组包括一些潜在危险的转换,例如指针和整数之间的转换。除非需要显式强制转换,否则利用隐式转换可防止意外执行其中一种危险转换。
我确实看到此实现存在潜在问题,但它与您的问题无关。我觉得还是不细说为好,不要把我的回答误认为是对这个功能的认可