是什么导致“警告:条件表达式中的指针/整数类型不匹配”?

时间:2012-11-10 01:27:08

标签: c macros enums

我有一个枚举,一个宏定义和一个都使用枚举的方法。我无法编译。请考虑以下几段代码。

typedef enum fruits_t
{
    APPLE,
    ORANGE,
    BANANA
} fruits_t;

#define KEY_TO_VALUE(x) ((x == APPLE) ? 0 :  \
                         (x == ORANGE) ? 1 :  \
                         (x == BANANA) ? 2 : \
                         "Undefined")

static void foo(char fruit) {
    if (fruit == KEY_TO_VALUE(APPLE)) {
        /* do something */
    }
}

编译,但我收到以下警告。

warning: pointer/integer type mismatch in conditional expression

warning: comparison between pointer and integer

为什么呢?我是C的新手,所以如果你能解释一些经验丰富的C开发人员看似显而易见的事情,我会很感激。我的大多数编程知识都是基于Java的。

2 个答案:

答案 0 :(得分:10)

编译器正试图找出程序中每个表达式的类型。

x > 0 ? 5 : "no"之类的表达式使编译器脱颖而出。如果x大于零,则类型为int,但如果不是,则类型为const char *。这是一个问题,因为没有从指针到int的自动转换(反之亦然)。所以编译器警告它。

解决方案是确保无论fruit的值是什么,KEY_TO_VALUE的值都是单一类型。例如,代替“Undefined”(类型为const char *,因为它是文字字符串),您可以使用特殊值,例如-1。

另请注意,APPLE是一个值为0的常量,ORANGE是一个值为1的常量,BANANA是一个值为2的常量(这是{ {1}}有效)。因此,您不需要enum,因为常量已经具有所需的值。您可以直接将KEY_TO_VALUEfruit进行比较:

APPLE

答案 1 :(得分:3)

在C语言中,?:运算符对其第二个和第三个操作数强加了以下要求

  

以下其中一项适用于第二和第三个操作数:

     
      
  • 两个操作数都有算术类型;
  •   
  • 两个操作数具有相同的结构或联合类型;
  •   
  • 两个操作数都有void类型;
  •   
  • 两个操作数都指向兼容类型的限定或非限定版本的指针;
  •   
  • 一个操作数是指针,另一个是空指针常量;或
  •   
  • 一个操作数是指向对象或不完整类型的指针,另一个是指向合格或非限定版本的void的指针。
  •   

在你的代码中,你将算术类型和指针类型(字符串文字衰减到char *类型)混合为?:的第二和第三个操作数。这是不允许的。

非正式地说,你是怎么想出这个主意的?像x == BANANA ? 2 : "Undefined"这样的东西是什么类型的? intchar *?还有别的吗?

请注意,允许混合指针值和常量0,即表达式x == APPLE ? 0 : "Undefined"实际上会编译而没有任何问题。但是,0将被解释为空指针常量,整个表达式将具有指针类型(char *)并在x == APPLE时计算为空指针是真的。这可能不是你想要的。