为啥 FxCop 会在此 C# 代码中发出有关溢出 (CA2233) 的警告?

Posted

技术标签:

【中文标题】为啥 FxCop 会在此 C# 代码中发出有关溢出 (CA2233) 的警告?【英文标题】:Why is FxCop warning about an overflow (CA2233) in this C# code?为什么 FxCop 会在此 C# 代码中发出有关溢出 (CA2233) 的警告? 【发布时间】:2010-04-15 01:34:15 【问题描述】:

我有以下函数从一个高字节和一个低字节中获取一个int:

public static int FromBytes(byte high, byte low)

    return high * (byte.MaxValue + 1) + low;

当我使用 FxCop 分析程序集时,我收到以下严重警告:

CA2233:操作不应该溢出 算术运算不应该 在没有首先验证的情况下完成 防止溢出的操作数。

我看不出这怎么可能溢出,所以我只是假设 FxCop 过于热心了。 我错过了什么吗?可以采取哪些措施来纠正我所拥有的(或至少让 FxCop 警告消失!)?

【问题讨论】:

我赌的是“byte.MaxValue + 1”部分。 你赌错了。他的代码不会导致溢出,因为 byte.MaxValue 在添加步骤发生之前总是会隐式转换为 int。 -- 任何时候方法执行算术运算并且不预先验证操作数(以防止溢出),您将得到 CA2233。在 MSDN 上msdn.microsoft.com/en-us/library/ms182354.aspx 有很多关于如何解决此问题的示例 阅读msdn.microsoft.com/en-us/library/ms182354.aspx 【参考方案1】:

它以字节计算的形式进行。

试试这个

return (int)high * ((int)byte.MaxValue + 1) + (int)low;

【讨论】:

我正要写这个!又好又快。 :) -1! (如果可以的话!)这是不正确的。您不需要将 byte.MaxValue 转换为整数 - 当您添加整数和字节时 - 字节会自动转换为整数 - 这是隐式转换的重点。为了证明,请注意: public static int GetValue() return Byte.MaxValue + 1 返回值 256。 Byte + Int = Int。另外,请注意您提供的代码不会使 CA2233 FxCop 警告消失。只需 (i + 1)(其中 i 是一个 int)就会导致此警告。【参考方案2】:

字节加法和多结果是整数。这里的最大值是 65535,不会溢出 int。只是压制错误。

byte a = 1;
byte b = 2;
object obj = a + b

obj 的类型为 int

试试这个:

        byte high = 255;
        byte low = 255;
        checked
        
            int b = high * (byte.MaxValue + 1) + low;   
        

没问题。

或者试试这个

【讨论】:

【参考方案3】:

作为Daniel A. Whitepointed out,您收到消息是因为“(byte.MaxValue + 1)”溢出了一个字节。

但我不会进行转换和相乘,而是像下面的代码那样简单地移动位:

public static int FromBytes(byte high, byte low) 
    return high << 8 | low;

作为副作用,此代码可能会执行得更好。我还没有检查生成的 IL 或 x86 以查看编译器和/或 JITter 是否足够聪明以优化原始表达式。

【讨论】:

同样,byte.MaxValue + 1 不会溢出字节。他收到消息是因为他没有验证他的操作数。由于您的代码不执行任何算术运算,而仅执行二进制逻辑,因此它会为您的代码消失。有关详细信息,请参阅msdn.microsoft.com/en-us/library/ms182354.aspx。【参考方案4】:

这是它最终停止为我抱怨 CA2233 的 2 种方式:

    public static int FromBytes(byte high, byte low)
    
        int h = high;
        return h * (byte.MaxValue + 1) + low;
    

    public static int FromBytes2(byte high, byte low)
    
        unchecked
        
            return high * (byte.MaxValue + 1) + low;
        
    

我认为这可能是规则中的错误。

【讨论】:

以上是关于为啥 FxCop 会在此 C# 代码中发出有关溢出 (CA2233) 的警告?的主要内容,如果未能解决你的问题,请参考以下文章

为啥受保护的构造函数会在此代码中引发错误?

513 错误代码(退出代码)FxCop 使用 C#

为啥 FxCop 坚持使用 IDisposable 作为结构

我应该使用 FxCop,为啥?

FxCop - CA1034 错误 - 为啥?

为啥 GCC 不对无法访问的代码发出警告?