为什么具有负值的枚举会导致Objective-C / C出现问题?

时间:2011-02-18 22:46:52

标签: objective-c c enums llvm signed

出于各种实现原因,我已经定义了以下枚举:

typedef enum HBSnakeMovementDirection
{
    HBSnakeMovementDirectionUp = 1,
    HBSnakeMovementDirectionDown = -1,
    HBSnakeMovementDirectionRight = 2,
    HBSnakeMovementDirectionLeft = -2
}
HBSnakeMovementDirection;

但是,如果我尝试使用HBSnakeMovementDirectionRight,我会收到以下警告:

  

Implicit conversion changes signedness: 'int' to 'HBSnakeMovementDirection'

任何其他枚举值都没有问题。这有什么问题?我认为它可能与混合负面和正面枚举值有关,但我无法找到任何关于此的确定性。

(我能够提出所有积极的枚举值,让我可以解决这个问题,但它仍然困扰我,所以我想我会问它。)

我应该说,就像我的所有项目一样,我几乎发出了所有警告 - 因此-Wconversion的投诉 - 并将其视为错误。 (我希望在编译时尽可能严格。)我正在使用LLVM 1.6。

更新1 :从字面上看,使用HBSnakeMovementDirectionRight会产生前面的警告:

HBSnakeMovementDirection movementDirectionRight = HBSnakeMovementDirectionRight;

我必须将HBSnakeMovementDirectionRight投射到HBSnakeMovementDirection以使警告无声。

更新2 :根据要求,这是我的机器上发布的整个构建命令:

http://pastie.org/1580957

更新3 :以下是我正在GitHub上托管的确切项目:

https://github.com/LucasTizma/Hebi

具体来说,以下树:

https://github.com/LucasTizma/Hebi/tree/89262e2e53881584daf029e3dd5f1e99dfbd6f96

3 个答案:

答案 0 :(得分:3)

正如Darren所说,它确实看起来像编译器错误,Dave说它不会发生在Clang 2.0上。

我发现以下类型定义使用Clang 1.6编译OP代码:

typedef enum HBSnakeMovementDirection 
{
    HBSnakeMovementDirectionUp = 1,     // Default movement direction upon initialization via -init
    HBSnakeMovementDirectionDown = -1,
    HBSnakeMovementDirectionLeft = -2,
    HBSnakeMovementDirectionRight = 2,
    NBSnakeMovementDirectionNone = -3
}
HBSnakeMovementDirection;

(请注意额外的NBSnakeMovementDirectionNone

这可能与已修复的LLVM错误1884有关。

答案 1 :(得分:1)

我可以重现这一点。它对我来说当然看起来像编译器错误。枚举中存在负值会导致编译器错误地认为“2”的值超出了枚举的范围,因此警告。

无论您指定“2”还是“HBSnakeMovementDirectionRight”,行为都是相同的:它接受1并拒绝2.

编辑:我在现有的iPhone项目中对此进行了测试,设置了编译器LLVM 1.6并设置了-Wconversion标志。

typedef enum HBSnakeMovementDirection
{
    neg1 = -1,
    pos1 = 1,
    pos2 = 2,
} HBSnakeMovementDirection;

HBSnakeMovementDirection d = -3;  // Warning: Can't convert int to HBSnakeMovementDirection
HBSnakeMovementDirection d = -2;  // OK
HBSnakeMovementDirection d = -1;  // OK
HBSnakeMovementDirection d = 0;  // OK
HBSnakeMovementDirection d = 1;  // OK
HBSnakeMovementDirection d = 2;  // Warning: Can't convert int to HBSnakeMovementDirection
HBSnakeMovementDirection d = pos2;  // Warning: Can't convert int to HBSnakeMovementDirection

答案 2 :(得分:1)

绝对看起来像编译器错误。我在Xcode 3中打开了项目并进行了编译,并得到了错误。当我在Xcode 4中打开项目并使用clang2.0编译器时,我没有收到任何警告。