我有一个多线程应用程序,它将数据存储为以下联合的实例数组
union unMember {
float fData;
unsigned int uiData;
};
Run Code Online (Sandbox Code Playgroud)
存储此数组的对象知道联合中的数据是什么类型,因此在检索正确类型时我不会遇到UB问题.但是在程序的其他部分,我需要测试这两个联合实例之间的相等性,并且在这部分代码中,真正的内部数据类型是未知的.结果是我无法使用这种方法测试联合的相等性
unMember un1;
unMember un2;
if (un1 == un2) {
// do stuff
}
Run Code Online (Sandbox Code Playgroud)
因为我得到编译错误.因此,我只是比较联合的浮动部分
if (un1.fData == un2.fData) {
// compiles but is it valid?
}
Run Code Online (Sandbox Code Playgroud)
现在考虑到我已经读过它是UB访问一个联盟的任何部分而不是最后写的那部分(这是繁琐的写,但我可以想到没有更明确的方式来说这个)我想知道代码是否以上是检查我的联合实例的相等性的有效方法?
这让我意识到内部我不知道工会是如何运作的.我曾假设数据只是存储为一个位模式,你可以根据你所喜欢的方式解释它,具体取决于联合中列出的类型.如果不是这样,那么测试两个联合实例的相等性的安全/正确方法是什么?
最后,我的应用程序是用C++编写的,但我意识到工会也是C的一部分,那么这两种语言对它们的处理方式有何不同?
通常,您需要预先添加当前联合类型的某种指示符:
struct myData
{
int dataType;
union {
...
} u;
}
Run Code Online (Sandbox Code Playgroud)
然后:
if (un1.dataType != un2.dataType)
return (1 == 0);
switch(un1.dataType)
{
case TYPE_1:
return (un1.u.type1 == un2.u.type1);
case TYPE_2:
...
}
Run Code Online (Sandbox Code Playgroud)
无论如何,语法
if (un1.fData == un2.fData) {
// compiles but is it valid?
}
Run Code Online (Sandbox Code Playgroud)
哪个编译并且有效,可能由于两个原因而无法工作.一个是,正如你所说,也许un2包含一个整数而不是一个浮点.但在这种情况下,平等的测试将正常终将以失败告终.第二个是两个结构都有一个浮点,它们代表相同的数字,并有轻微的机器错误.然后测试将告诉你数字是不同的(它们是一点一点),而它们的"含义"是相同的.
通常比较浮点数
if (dabs(f1 - f2) < error)
Run Code Online (Sandbox Code Playgroud)
避免这个陷阱.