0%

C++使用列表初始化避免缩窄转换错误

使用取值范围较大的变量来初始化取值范围较小的变量时,将面临出现缩窄转换错误的风险,因为编译器必须将大得多的值存储到容量没那么大的变量中,下面是一个这样的示例:

1
2
int largeNum = 5000000;
short smallNum = largeNum; // compiles OK, yet narrowing error

缩窄转换并非只能在整型之间进行,但如果使用double 值来初始化float 变量、使用int 值来初始化float 或double 变量,或者使用float 值来初始化int 变量,可能导致缩窄转换错误。有些编译器可能发出警告,但这种警告并不会导致程序无法通过编译。在这种情况下,程序可能在运行阶段出现bug,但这种bug 并非每次运行时都会出现。

为避免这种问题,C++11 引入了列表初始化来禁止缩窄。要使用这种功能,可将用于初始化的变量或值放在大括号({})内。列表初始化的语法如下:

1
2
3
4
5
int largeNum = 5000000;
short anotherNum{ largeNum }; // error! Amend types
int anotherNum{ largeNum }; // OK!
float someFloat{ largeNum }; // error! An int may be narrowed
float someFloat{ 5000000 }; // OK! 5000000 can be accomodated

这种功能的作用虽然不明显,但可避免在执行阶段对数据进行缩窄转换导致的bug:这种bug 是不合理的初始化导致的,难以发现。