"cast specifies a conversion" 是什么意思?

What's the meaning of "cast specifies a conversion"?

在 C 1999 注释 86 中,讲到 6.5.4 5(我的粗体)

If the value of the expression is represented with greater precision or range than required by the type named by the cast (6.3.1.8), then the cast specifies a conversion even if the type of the expression is the same as the named type.

signed char a = -2;
unsigned char b = 1;
b = (short)a + (short)b;

b = (short)a + (short)b;。这是

的例子

If the value of the expression is represented with greater precision or range than required by the type named by the cast (6.3.1.8),

因为如果没有强制转换,ab 都会被提升为 int,这比 short 更高的精度或范围演员命名的类型(假设 short 是 16 位,int 是 32 位)。

那么,在这种情况下,后一句

then the cast specifies a conversion even if the type of the expression is the same as the named type.

我想知道这对 b = (short)a + (short)b; 有何影响。

我的想法很简单。因为 (cast) 比加法 + 有更高的优先级,首先 ab(short) 转换,然后 + 的两个操作数被转换通常的算术转换。但是“即使表达式的类型与命名类型相同,那么强制转换也指定转换”这句话让我感到困惑。

这大约是 floating-point 种类型。整数类型不受影响。

b = (short)a + (short)b;. This is an example of “If the value of the expression is represented with greater precision or range than required…”

不,该语句中的整数转换不是这样的例子。 C 2018 6.3.1.8 2(在 C 1999 中相同)告诉你它是关于 floating-point 类型:

The values of floating operands and of the results of floating expressions may be represented in greater range and precision than that required by the type; the types are not changed thereby.

这里发生的是 C 标准允许 floating-point 表达式的计算范围和精度比它们的标称类型更大,根据 C 2018 5.2.4.2.2 10:

Except for assignment and cast (which remove all extra range and precision), the values yielded by operators with floating operands and values subject to the usual arithmetic conversions and of floating constants are evaluated to a format whose range and precision may be greater than required by the type…

(在 C 1999 中,类似的文本出现在 5.4.2.2.2 7。差异可能有一些意义,但这里不讨论。)

这意味着当您使用 double 计算表达式时,编译器可能会生成使用 long double 的代码。或者,当您使用 float 计算表达式时,编译器可能会使用 doublelong double。这使得更容易,例如,在具有加载和存储指令的处理器上实现 C single-precision (float) 或 double-precision (double) floating-point 数据,但其中包含仅用于计算 double-precision floating-point 的指令,不适用于 single-precision.

你从C 1999引用的note 86已经提升为C 2018的规范文本,如6.5.4 6:

If the value of the expression is represented with greater range or precision than required by the type named by the cast (6.3.1.8), then the cast specifies a conversion even if the type of the expression is the same as the named type and removes any extra range and precision.

这告诉你的是,强制转换必须“移除”额外的范围和精度。 (这是不幸的措辞;最好说该值使用任何适用的舍入规则舍入为命名类型中可表示的值,通常为 round-to-nearest ties-to-even。)

在C 2018 6.3.1.5 1(C 1999中没有),关于floating-point类型之间的转换,我们看到:

… Results of some implicit conversions may be represented in greater range and precision than that required by the new type (see 6.3.1.8 and 6.8.6.4).

所以情况是这样的:Floating-point 可以使用额外的范围和精度计算表达式。当存在隐式转换时,例如将 float 乘以 double(通常的算术转换将 float 转换为 double),这个额外的范围和精度可能保持。但是,当您在源代码中进行强制转换时,必须执行“实际转换”,将具有额外精度的值转换为标称类型中可表示的值。这就是所谓的强制转换指定转换的意思。

虽然赋值中的转换是隐式的,但也需要赋值来执行此转换,正如我们在上面引用的 5.2.4.2.2 10 中所告知的那样。注释 65 到 6.3.1.8 2:

中也指出了这一点

The cast and assignment operators are still required to remove extra range and precision.

可能需要注意的是,return 语句执行隐式转换,但不需要删除额外的范围或精度。