简体   繁体   English

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

[英]'invalid operands to binary operands' while comparing two unions

I am writing a code for implementing linked list in C that is type agnostic. 我正在编写用于在C语言中实现类型无关的链表的代码。 This is what I am trying to do. 这就是我想要做的。

  1. Create a union that can store either of these: int, char*, double, char. 创建一个可以存储以下任意一个的联合:int,char *,double,char。

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

  2. An enum to keep track of what element the union is storing. 一个枚举,用于跟踪联合存储的元素。

    enum { NUM, STR, REAL, CHAR };

  3. A struct that will store the node values. 将存储节点值的结构。

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

  4. Since I might have more than one list, I am also creating a container for the node as, 由于我可能有多个列表,因此我还为该节点创建了一个容器,

    struct list { struct node *head; };

Now I want to create a funtion that will fetch a element from the list. 现在,我想创建一个从列表中获取元素的功能。 The function is, 函数是

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

When I compile the code, clang throws me this error, 当我编译代码时, clang抛出此错误,

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

Here 这里

if(i->data == key) {

its comparing union variable which is invalid as told in Harbison and Steele book Harbison和Steele所述,其比较联合变量无效

Structures and unions cannot be compared for equality , even though assignment for these types is allowed. 即使允许对这些类型进行分配,也无法比较结构联合是否相等 The gaps in structures and unions caused by alignment restrictions could contain arbitrary values, and compensating for this would impose an unacceptable overhead on the equality comparison or on all operations that modified structure and union types. 由对齐限制引起的结构和联合中的间隙可能包含任意值,对此进行补偿将对相等性比较或修改结构和联合类型的所有操作造成不可接受的开销。

you can compare union members like 您可以比较工会会员,例如

if(i->data.num == key.num) {
 /*  some code */    
}

Moved this to an answer since it's no longer comment appropriate. 将其移至答案,因为它不再适合注释。

The root cause of the problem is that if the union member are different sizes, you are not guaranteed that the comparison will succeed if write to smaller members but then compare larger members. 问题的根本原因是,如果并集成员的大小不同,则不能保证如果写入较小的成员然后比较较大的成员,则比较将成功。 For example, if you wrote to the alph member of both unions, but then compare the num members, the one byte that holds alph will compare correctly, but even if they're equal, the remaining bytes in num may be different, leading to a "false unequal" result. 例如,如果您写了两个联合的alph成员,然后比较了num成员,则保存alph的一个字节将正确比较,但是即使它们相等, num的剩余字节也可能会不同,从而导致“错误的不平等”结果。 Same with writing to the num members and then comparing the real members. 与写入num成员然后比较real成员相同。

So to avoid this problem, you need to first compare the two type values, and only if they match compare the appropriate pair of union members. 因此,为避免此问题,您需要首先比较两个type值,并且仅在它们匹配时比较相应的并集成员对。 The selection of which members to compare can most easily be done with a switch. 可以通过开关轻松选择要比较的成员。

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;
}

I'll add a note that how you handle case STR: is dependant on the behavior you want. 我将添加一条注释,说明如何处理case STR:取决于所需的行为。 If you want the two stings to match, use strcmp() if you want them to refer to the same string, use == on the two pointers. 如果要使两个字符串匹配,请使用strcmp()如果它们要引用相同的字符串),请在两个指针上使用== I suspect that the former will be a more useful way to do things, but it's worth noting the exact pointer comparison. 我怀疑前者将是一种更有用的处理方法,但值得注意的是确切的指针比较。 Somewhat akin to the difference between == and === in PHP. 类似于PHP中=====之间的区别。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM