在C ++中,当我在-128,127范围之外的整数值上使用static_cast <char>时会发生什么?

在使用g ++的i386 Linux上编译的代码中,我使用了static_cast<char>()强制转换为可能超出-128,127 char的有效范围的值。 没有错误或exception,所以我使用了生产中的代码。

现在的问题是,我不知道这个代码可能会在这个范围之外的值被抛出时如何performance。 如果数据被修改或截断没有问题,我只需要知道这个修改是如何在这个特定的平台上运行的。

另外如果使用C风格的演员( (char)value )会发生什么? 它会有不同的performance吗?

在你的情况下,这将是一个明确的类型转换。 或者更准确地说是一个完整的转换。
标准说这个(4.7):

如果目标类型是有符号的,那么如果目标类型可以用目标类型(和位域宽度)表示,则该值不变。 否则,该值是实现定义的。

所以你的问题是实现定义的。 另一方面,我还没有看到一个编译器,不只是将较大的值截断为较小的值。 我从来没有见过使用上述规则的编译器。 所以只需要将你的integer/short转换为char就相当安全。

我不知道C心的规则,我真的试图避开它们,因为不容易说哪个规则会起作用。

这在标准的第4.7节(整体转换)中得到处理。

答案取决于是否在实现问题char是有符号的或无符号的。 如果它是无符号的,则应用模运算。 C ++ 11的§4.7/ 2指出:“如果目标类型是无符号的,则结果值是与源整数相同的最小无符号整数(模2 n,其中n是用于表示无符号类型的位数) “。 这意味着如果输入的整数不是负数,则会出现正常的位截断。 如果是否定的,如果负数用2的补码表示,则相同,否则转换将会改变。

如果char被签名,则C ++ 11的§4.7/ 3适用:“如果目标类型是有符号的,如果目标类型可以用目标类型(和位域宽度)表示,则值不变;否则,值是实现定义“。 所以这取决于您使用的特定实现的文档。 话虽如此,在2的补码系统(即所有正常使用的系统)中,我还没有看到除了正常位截断以外的其他字符类型的情况:除了其他任何东西,凭借§3.9.1/ 1所有字符类型(char,unsigned char和signed char)都必须具有相同的对象表示和对齐方式。

C风格的情况下,显式的static_cast和隐式缩小转换的效果是相同的。

从技术上来说,无符号类型的语言规范同意插入一个普通的基数2。 而对于未签名的普通的base-2,其扩展和截断很明显。

然而,当无符号的时候,这些规范更加“宽容”,允许不同类型的处理器使用不同的方式来表示有符号的数字。 而且由于相同的数字可能在不同的平台上有不同的表示,所以实际上不可能提供关于添加或删除位时发生什么的描述。

由于这个原因,语言规范仍然比较模糊,说“ 如果目标类型(和位域宽度)可以表示值则值不变;否则,该值是实现定义的

换句话说,编译器制造商必须尽最大努力保持数值。 但是,如果不能做到这一点,他们就可以自由地适应对他们更有效的方式。