通过将long long int
类型的变量赋值给int64_t
类型的变量,将long long int
类型的值转换为int64_t
类型的值。这种将long long int
转换为int64_t
的方法有哪些潜在问题?
#include <stdio.h>
#include <stdint.h>
int main (void) {
long long int num = 9223372036854775807; // 2^63-1
int64_t num64_t = num;
printf("%lldn", num64_t);
return 0;
}
一个问题可能是ISO/IEC 9899:1999标准在第22页,§5.2.4.2.1中规定long long int
的范围至少±2^63-1,而int64_t
类型的正好64位宽度。可能在某些机器上,long long int
类型的值通过使用超过64位来存储吗?如果num
的值大于2^63-1或小于-(2^63-1),这可能导致上面的程序崩溃,因为num64_t
只有64位可用。如果这是一个问题:还有其他问题吗?更一般地说:上面的方法是一个安全的方式来转换类型long long int
的值到类型int64_t
的值吗?如果不是,如何避免这些问题?
一个问题可能是ISO/IEC 9899:1999标准第22页,§5.2.4.2.1规定
long long int
的范围至少±2^63-1,而int64_t类型的正好64位宽度。
C99已经过时了,但最新版本的标准(当前是C2017)规定了同样的事情。是的,这是一个潜在的问题:与其说是类型的大小,不如说是它们可表示值的范围。如果您尝试将long long int
值赋给int64_t
,并且该值不能表示为int64_t
,则结果要么是实现定义的,要么引发实现定义的信号。
是否在某些机器上,使用超过64位的长度存储long long int类型的值?
是的,这是可能的。并且long long int
的范围比int64_t
的范围宽。
如果
num
的值大于2^63-1或小于-(2^63-1),则可能导致上述程序崩溃,因为num64_t
只有64位可用。
是的,如果结果是引发一个信号,那么可能导致程序崩溃。然而,更典型的情况是,转换成功了,但(必然)在受让人中产生了不同的值。这可能更糟,因为您没有立即注意到问题。
如果这是一个问题:还有其他的吗?更一般地说:上面的方法是将类型为
long long int
的值转换为类型为int64_t
的值的安全方法吗?
将整数值赋值给任何整型对象都会自动将该值转换为目标类型。当赋值的值在目标类型中可表示时,允许从一种整数类型转换到另一种整数类型,并且允许保持值。尽管与您的具体情况无关,但如果目标类型是无符号的,即使原始值在无符号目标类型中不可表示,也允许这样的转换并定义得很好。我已经描述了在所有其他情况下的影响。
也就是说,不,除了已经描述的尝试将超出范围的值赋给目标有符号整数对象的后果之外,没有其他问题需要关注。