【问题标题】:How to get warning when comparing two enum value比较两个枚举值时如何得到警告
【发布时间】:2018-07-02 11:55:15
【问题描述】:

在这个Objective-C的小DEMO中:

第一个枚举:

typedef NS_ENUM(NSUInteger, Day) {
     DaySunday,
     DayMonday,
     DayTuesday
};

第二个枚举:

typedef NS_ENUM(NSUInteger, Month) {
    MonthJanuary,
    MonthFebruary,
    MonthMarch,
    MonthApril
};

比较时:

Day sunday = DaySunday;
Month january = MonthJanuary;
if (sunday == january) {
     NSLog(@"case1 with warning");
  }
if (DaySunday == january) {
     NSLog(@"case2 without warning");
  }

和 Xcode 快照:

那么我如何在 case2 中收到警告?

【问题讨论】:

  • 也许如果你使用 Day.DaySunday 那么它会显示警告。目前它只将这两个值都作为整数。

标签: objective-c xcode enums gcc-warning


【解决方案1】:

(Objective-)C 中的枚举类型是非常弱的类型。根据 C 标准,每个枚举常量(您的 january 等)都有一个整数类型,不是枚举的类型。此外,枚举类型的值会在需要时隐式转换为整数类型。

两个 操作数都是枚举类型时,Clang 会向您发出警告,并且它只是一个 警告,因为根据 C 标准,整数之间的比较是正确的价值观。

在您的DaySunday == january 中,左操作数具有整数类型,右操作数隐式转换为整数类型,因此这又是完全合法且正确的标准 C。Clang 可以选择发出警告,为什么不这样做可能取决于 Clang 内部的设计决策或设计结果。

感谢 Clang 经常在标准 C 不需要它们的地方给出警告,但是你不能依赖它来显示 C 中的所有陷阱。

要解决您的问题,您可以根据需要将文字转换为枚举类型 (Day)DaySunday == january,但您可能会合理地认为这会使 C 看起来更糟 ;-)

【讨论】:

    【解决方案2】:

    我不确定为什么会发生这种行为,但它很奇怪而且很酷。要获得警告,您必须将 DaySunday 显式转换为 Day 类型。

    if ((Day)DaySunday == january) {
        NSLog(@"case2 without warning");
    }
    

    january 显式转换为Month 不会触发警告,因此看起来静态分析器正确地将january 视为Month 类型(因为您是这样声明的),但是是隐式的转换 DaySunday 以进行比较。

    公平地说,第一种情况下的警告实际上并不是理想的行为,因为DayMonth 都是 NSUInteger,因此具有可比性。正如您在运行此代码时观察到的那样,两个比较都是正确的,这意味着警告实际上没有意义。

    【讨论】:

      【解决方案3】:

      您必须将 enum 更改为 int 才能删除警告

       if ((int)sunday == (int)january) {
          NSLog(@"case1 with warning");
      }
      

      【讨论】:

      • 问题是如何引起警告,而不是如何防止警告。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多