比较两个并集时“无效的操作数到二进制操作数”

时间:2018-09-10 04:34:38

标签: c compiler-errors linked-list binary-operators

我正在编写用于在C语言中实现类型无关的链表的代码。这就是我想要做的。

  1. 创建一个可以存储以下任意一个的联合:int,char *,double,char。

    union element { int num; char* str; double real; char alph; };

  2. 用于跟踪联合存储的元素的枚举。

    enum { NUM, STR, REAL, CHAR };

  3. 将存储节点值的结构。

    struct node { int type; union element data; struct node *next; };

  4. 由于我可能有多个列表,因此我还将为该节点创建一个容器,

    struct list { struct node *head; };

现在,我想创建一个从列表中获取元素的函数。功能是

node* findkey(list *l, union element key)
{
    node *i=list->head;
    while(!i) {
        if(i->data == key) {
            return i;
        i=i->next;
    }
    return NULL;
}

编译代码时,clang抛出此错误,

linkedlist.c:33:11: error: invalid operands to binary expression ('union element' and
      'union element')
                if(i->data == key)
                   ~~~~ ^  ~~~
1 error generated.

2 个答案:

答案 0 :(得分:1)

这里

header?

其比较联合变量无效,如Harbison and Steele book所述

  即使

结构工会,也无法比较平等   这些类型的分配是允许的。结构上的差距和   对齐限制导致的并集可以包含任意   值,并对此进行补偿将导致无法接受   相等比较或所有已修改操作的开销   结构和联合类型。

您可以像这样比较工会会员

if(i->data == key) {

答案 1 :(得分:-1)

将其移至答案,因为它不再适合注释。

此问题的根本原因是,如果并集成员的大小不同,则不能保证如果写入较小的成员然后比较较大的成员,则比较将成功。例如,如果您写了两个联合的alph成员,然后比较了num成员,则保存alph的一个字节将正确比较,即使它们相等,num中的其余字节可能会有所不同,从而导致“错误的不相等”结果。与写入num成员,然后比较real成员相同。

因此,为避免出现此问题,您需要首先比较两个type值,并且只有在它们匹配时,才需要比较适当的一对联合成员。可以通过切换最轻松地选择要比较的成员。

node* findkey(list *l, union element key, int type)
{
    node *i=list->head;
    while(!i) {
        // compare types first, assume no match if they differ
        if(i->type != type) {
            continue
        }
        switch (type)
        {
        case NUM:
            if(i->data.num == key.num) {
                return i;
            }
            break;
        case STR:
            ...
        case REAL:
            ...
        case CHAR:
            ...
        }
        i=i->next;
    }
    return NULL;
}

我将添加一条注释,说明如何处理case STR:取决于您想要的行为。如果要使两个字符串匹配,请使用strcmp(),如果要它们引用相同的字符串,请在两个指针上使用==。我怀疑前者将是一种更有用的处理方法,但值得注意的是确切的指针比较。类似于PHP中=====之间的区别。