为什么我需要这个奇怪的演员用于enum算术?

时间:2016-04-22 07:22:02

标签: c enums casting

我有这段代码:

typedef enum myEnum_e
{
    VAL0,
    VAL1
} myEnum;

void func(void)
{
    myEnum val = (myEnum) 0;

    while(/*Do something*/)
    {
        val = val + ((myEnum)1); // <= Warning here
    }
}

这段代码产生警告:

  

与其他类型混合的枚举类型

为了清理这个,我最终得到了:

void func(void)
{
    myEnum val = (myEnum) 0;

    while(/*Do something*/)
    {
        val = ((myEnum) val + 1); // <= NO Warning here
    }
}

有人能说出为什么第一个表格不正确吗? 我觉得第二个没有第一个那么有意义。 我的意思是我更愿意阅读:

  

将1(被视为myEnum值)添加到val(并将结果存储在val

  

存储在val val + 1中,被视为myEnum

注意:这是TI C28x编译器(适用于TI C2000 MCU)。

编辑:

我的真正应用是为嵌入式软件定义自定义UART通信。 所以这就是我所做的:

typedef enum e_frame
{
    FRAME_A,
    FRAME_B,
    FRAME_C,
    FRAME_COUNT
} frame_e;

typedef enum e_frameId
{
    FRAMEID_A = 0x0A,
    FRAMEID_B = 0x42,
    FRAMEID_C = 0xFF
} frameId_e;


const frameInfo_s FramesInfo[FRAME_COUNT] =
{
        [FRAME_A] =
            {
                    .id = MCM_FRAMEID_A,
                    // And other stuff
            },
        [FRAME_B] =
            {
                    .id = MCM_FRAMEID_B,
                    // And other stuff
            },
        [FRAME_C] =
            {
                    .id = MCM_FRAMEID_C,
                    // And other stuff
            }
}

最后ID到frame_e函数:

frame_e UAR_FrameId2Frame(frameId_e id)
{
    frame_e frame = (frame_e) 0;

    while(FramesInfo[frame].id != id && frame < FRAME_COUNT)
    {
        frame = (MCM_frames_e)(frame + 1);
    }

    return frame;
}

3 个答案:

答案 0 :(得分:1)

我这里没有任何警告:

#include <stdio.h>

typedef enum myEnum_e
{
    VAL0,
    VAL1
} myEnum;


int main (int argc, char *argv[]) {
    myEnum val = 0;

    while( 1 /*Do something*/)
    {
        val =  val + 1;
    }
    return 0;
}

编译:GCC 4.2.1

编译命令:gcc -Wall -pedantic x.c

答案 1 :(得分:0)

收到警告是件好事.C不是严格类型的语言,因此在混合可以相互强制的类型时不会出错。但混合类型有可能导致细微的运行时错误。因此,虽然内部枚举和整数是相同的类型,但您不应该混合它们。您应该考虑使用初始化为1的枚举增量变量。

答案 2 :(得分:-1)

首先,拥有大量演员阵容的代码阅读起来不是很愉快,但是,这只是一个品味问题。

如果您打算进行算术运算,则可能需要明确定义枚举值。无论如何这样做是有风险的,因为你最终可能会得到一个超出范围的值。

如果您向VAL0添加3该怎么办?

想一想,这是什么意思?你已经声明了一个枚举,但是你现在获得的值不再是一个有效的枚举。使用枚举的原因主要是您希望限制序数的可能值的数量。

在你的情况下,拥有像VAL0和VAL1这样的常量会更有意义。

或者,如果你需要的只是遍历你的枚举,你可以这样做:

typedef enum myEnum_e
{
    VAL0,
    VAL1,
    // ...
    VAL66
} myEnum;

for(int i=VAL0; i<=VAL66; i++) {
  // do something here
}