gpt4 book ai didi

c# - 减去 uint 和 int 以及常量折叠

转载 作者:太空狗 更新时间:2023-10-29 18:35:22 25 4
gpt4 key购买 nike

基于这个有趣的问题:Addition of int and uint并使用 不断折叠 进行游戏,如 Nicholas Carey's 中所述answer ,我偶然发现了编译器看似不一致的行为:

考虑以下代码片段:

int i = 1;
uint j = 2;
var k = i - j;

此处编译器正确地将 k 解析为 long。正如前面提到的问题的答案中所解释的那样,这种特殊行为在规范中有明确的定义。

令我惊讶的是,在处理文字常量 或一般常量 时,行为会发生变化。阅读尼古拉斯·凯里的 answer我意识到行为可能不一致,所以我检查并确定:

const int i = 1;
const uint j = 2;
var k = i - j; //Compile time error: The operation overflows at compile time in checked mode.
k = 1 - 2u; //Compile time error: The operation overflows at compile time in checked mode.

k 在这种情况下被解析为 Uint32

在处理常量 时是否存在行为不同的原因,或者这是编译器中的一个小但不幸的“错误”(缺少更好的术语)?

最佳答案

来自C# specification version 5 , section 6.1.9, Constant Expressions only allow the following implicit conversions

6.1.9 Implicit constant expression conversions
An implicit constant expression conversion permits the following conversions:
* A constant-expression (§7.19) of type int can be converted to type sbyte, byte, short, ushort, uint, or ulong, provided the value of the constant-expression is within the range of the destination type.
• A constant-expression of type long can be converted to type ulong, provided the value of the constant-expression is not negative.

请注意,long 不在 int 转换列表中。

问题的另一半是二元运算只发生少量数字提升:

(来自第 7.3.6.2 节二进制数字提升):

  • If either operand is of type decimal, the other operand is converted to type decimal, or a binding-time error occurs if the other operand is of type float or double.
  • Otherwise, if either operand is of type double, the other operand is converted to type double.
  • Otherwise, if either operand is of type float, the other operand is converted to type float.
  • Otherwise, if either operand is of type ulong, the other operand is converted to type ulong, or a binding-time error occurs if the other operand is of type sbyte, short, int, or long.
  • Otherwise, if either operand is of type long, the other operand is converted to type long.
  • Otherwise, if either operand is of type uint and the other operand is of type sbyte, short, or int, both operands are converted to type long.
  • Otherwise, if either operand is of type uint, the other operand is converted to type uint.
  • Otherwise, both operands are converted to type int.

记住:intlong 的转换对于常量是禁止的,这意味着两个 args 都被提升为 uint

关于c# - 减去 uint 和 int 以及常量折叠,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26386201/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com