Search code examples
objective-ccenumsllvmsigned

Why are enums with negative values causing problems in Objective-C/C?


For various implementation reasons, I've defined the following enum:

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

However, if I try to use HBSnakeMovementDirectionRight, I get the following warning:

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

It has no problem with any of the other enum values. What's the problem here? I thought it might have to do with mixing negative and positive enum values, but I can't find out anything definitive about this.

(I was able to come up with all positive enum values that allow me to work around this issue, but it still stumped me, so I thought I'd ask about it.)

I should state that, as with all my projects, I enable almost every warning—hence, -Wconversion's complaints—and treat them as errors. (I like to be as strict as possible at compile time.) I'm using LLVM 1.6.

UPDATE 1: Literally any use of HBSnakeMovementDirectionRight results in the preceding warning:

HBSnakeMovementDirection movementDirectionRight = HBSnakeMovementDirectionRight;

I have to cast HBSnakeMovementDirectionRight to HBSnakeMovementDirection to silence the warning.

UPDATE 2: As requested, here is the entire build command that's being issued on my machine:

http://pastie.org/1580957

UPDATE 3: Here is the exact project I'm working on hosted on GitHub:

https://github.com/LucasTizma/Hebi

Specifically, the following tree:

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


Solution

  • As Darren said, it does look like a compiler bug, and Dave said it doesn’t happen with Clang 2.0.

    I’ve found that the following type definition makes the OP code compile with Clang 1.6:

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

    (note the additional NBSnakeMovementDirectionNone)

    This could be related to LLVM bug 1884, which has been fixed.