检查联合实例之间是否相等的正确方法是什么? [英] What is the correct way to check equality between instances of a union?

查看:52
本文介绍了检查联合实例之间是否相等的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个多线程应用程序,将数据存储为以下联合实例的数组

I have a multithreaded application that stores data as an array of instances of the following union

union unMember {
    float fData;
    unsigned int uiData;
};

存储此数组的对象知道联合中的数据是什么类型,因此在检索正确的类型时,UB不会出现问题.但是,在程序的其他部分,我需要测试这些联合的2个实例之间的相等性,并且在代码的这一部分中,真正的内部数据类型未知.其结果是,我无法使用这种方法测试联合的平等性

The object that stores this array knows what type the data in the union is and so I dont have problems with UB when retrieving the correct type. However in other parts of the program, I need to test equality between 2 instances of these unions and in this part of the code the true internal data type is not known. The result of this is that I can't test equality of the union using this kind of approach

  unMember un1;
  unMember un2;
  if (un1 == un2) {
     // do stuff
  }

当我得到编译器错误时.因此,我只是比较工会的浮动部分

as I get compiler errors. As such I am simply to compare the float part of the union

  if (un1.fData == un2.fData) {
     // compiles but is it valid?
  }

现在,考虑到我已经了解到它是UB访问联合的任何部分,而该部分不是最后写入的部分(笨拙地编写了该部分,但我想不出这种表达的方式),我想知道如果上面的代码是检查我的联合实例是否相等的有效方法?

Now given that I have read about it being UB accessing any part of a union that was not the part that was last written to (that is cumbersomely written but I can think of no more articulate way to say this) I am wondering if the code above is a valid way to check equality of my union instances??

这使我意识到,在内部,我不知道工会是如何工作的.我以为数据只是作为位模式存储的,并且您可以根据联合中列出的类型以任意方式解释它.如果不是这种情况,哪种安全/正确的方法可以测试两个工会实例的相等性?

This has made me realise that internally I have no idea how unions really work. I had assumed that data was simply stored as a bit pattern and that you could interpret that in whatever way you like depending on the types listed in the union. If this is not the case, what is a safe/correct way to test equality of 2 instances of a union?

最后,我的应用程序是用C ++编写的,但我意识到联合也是C的一部分,所以这两种语言对联合的处理方式有什么区别?

Finally, my application is written in C++ but I realise that unions are also part of C, so is there any difference in how they are treated by the 2 languages?

推荐答案

通常,您需要在当前联合类型的前面添加某种指示符:

In general, you need to prepend some kind of indicator of the current union type:

struct myData
{
    int dataType;
    union {
        ...
    } u;
}

然后:

if (un1.dataType != un2.dataType)
    return (1 == 0);
switch(un1.dataType)
{
    case TYPE_1:
        return (un1.u.type1 == un2.u.type1);
    case TYPE_2:
        ...
}

无论如何,语法

if (un1.fData == un2.fData) {
    // compiles but is it valid?
}

确实可以编译且有效的

可能由于两个原因而无法工作.正如您所说,其中之一可能是un2包含一个整数而不是一个浮点数.但是在那种情况下,相等性测试 通常还是会失败.第二个原因是两个结构均具有浮点,并且它们表示相同的数字,但存在轻微的机器错误.然后测试将告诉您数字是不同的(它们一点一点地不同),而它们的含义"是相同的.

which does compile and is valid, might not work for two reasons. One is that, as you said, maybe un2 contains an integer and not a floating point. But in that case the equality test will normally fail anyway. The second is that both structures hold a floating point, and they represent the same number with a slight machine error. Then the test will tell you the numbers are different (bit by bit they are), while their "meaning" is the same.

通常比较浮点数

if (dabs(f1 - f2) < error)

避免这种陷阱.

这篇关于检查联合实例之间是否相等的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆