使用byte作为枚举支持类型有什么问题吗?

时间:2013-08-04 23:49:42

标签: c# visual-studio-2012

鉴于以下计划:

using System;

namespace VS2012TestApp
{
    class Program
    {
        [Flags]
        public enum IoStatus : byte
        {
            ControlStore = (byte)128,
            Control = (byte)64,
            LogicalState = (byte)32,
            PhysicalState = (byte)16,
            NewEdge = (byte)4,
            Overload = (byte)2,
            NoLoad = (byte)1,
            None = (byte)0,
            Notify = (byte)8,
        }

        private static IoStatus Status = IoStatus.LogicalState;

        static void Main(string[] args)
        {
            Process(IoStatus.LogicalState | IoStatus.Overload, IoStatus.None);
        }

        private static void Process(IoStatus bitsSet, IoStatus bitsCleared)
        {
            bitsSet |= Status;
            bitsCleared |= ~Status;

            // Console.WriteLine("set {0}, clear {1}", bitsSet, bitsCleared);

            bitsSet &= ~(IoStatus.LogicalState | IoStatus.PhysicalState);
            bitsCleared &= ~(IoStatus.LogicalState | IoStatus.PhysicalState);

            Console.WriteLine("set {0}, clear {1}", bitsSet, bitsCleared);
        }
    }
}

在调试模式下Win7 x64位的VS2012(更新3)中,我得到:

  

设置Overload,清除NoLoad,Overload,NewEdge,Notify,Control,ControlStore

这就是我所期望的。

在发布模式下(启用和不启用优化):

  

设置过载,清除无

这是错误的。

目标平台AnyCPU或x86都会产生相同的输出。该代码在VS2008的调试和发布模式下工作正常。没试过VS2010。

编辑:在发布模式下在调试器中运行它会产生正确的行为。

可以通过执行以下任一操作来修复:

  1. 插入(当前已注释掉)Console.WriteLine()
  2. enum的支持类型更改为int
  3. Process的代码更改为:

    private static void Process(IoStatus bitsSet, IoStatus bitsCleared)
    {
         bitsSet = (bitsSet | Status) & ~(IoStatus.LogicalState | IoStatus.PhysicalState);
         bitsCleared = (bitsCleared | ~Status) & ~(IoStatus.LogicalState | IoStatus.PhysicalState);
    
         Console.WriteLine("Set {0}, Clear {1}", bitsSet, bitsCleared);
     }
    
  4. 所以问题是:我们是否以一种他们不想要的方式使用枚举,只是遇到了“未定义的行为”,或者这是编译器/抖动中的错误?

0 个答案:

没有答案