简体   繁体   English

工会的平等比较?

[英]Equality comparison of unions?

Is there a standard (or at least safe) way to compare unions for equality in C and/or C++? 是否存在一种标准(或至少安全)的方法来比较C和/或C ++中的同等式联合? I expect that bitwise comparison would be useful in a number of scenarios regardless of the last-assigned member in each union; 我希望按位比较在许多情况下都是有用的, 与每个联合中最后分配的成员无关 for instance, a particular bit-pattern could be reserved to mean "value is uninitialized", and it would be useful to be able to check if the union is uninitialized without needing to specify an "active" member. 例如,可以保留特定的位模式以表示“值未初始化”,并且无需指定“活动”成员就能够检查并集是否未初始化将很有用。

An example in C++ (though I think the concept extends to C using non-member functions): C ++中的一个示例(尽管我认为该概念使用非成员函数扩展到C):

union MyData
{
  public:
    // Assume I'm compiling this on a platform where the size of `int`
    // exceeds the size of `char*`, or that I'm using some combination
    // if `#ifdef`s or similar to ensure that my numeric type is sufficiently
    // large, or that I include an extra member that is known to be
    // exactly the size of the larger member, just for the sake of
    // comparison.
    int int_member;
    char* ptr_member;

    bool isInitialized() const
    {
      return (*this != INVALID_VAL);
    }

    bool operator==(MyData const& rhs)
    {
      return / * ??? */;
    }

  private:
    constexpr MyData INVALID_VAL { /* ??? */ };
}

// ... later, in client code...

MyData d;
bool initialized{d.isInitialized()};  // false
d.ptr_member = new char[32];
bool initialized{d.isInitialized()};  // true

Here, INVALID_VAL could probably be defined by setting int_member to the max negative int value, because that's an uneven value, so it won't be on a word boundary and therefore is highly unlikely to ever be assigned to the char* member (assuming that assignments typically come directly from new ). 在这里,可以通过将int_member设置为最大负int值来定义INVALID_VAL ,因为那是一个不均匀的值,因此它不会位于单词边界上,因此极不可能分配给char*成员(假设分配通常直接来自new )。

One possible implementation of operator== would be simply: operator==一种可能的实现方式是:

return int_member == rhs.int_member;

Even though it's not known whether int_member is the "active" member, I expect this to be safe, because I see no reason why a static cast from char* to int should fail or be problematic. 即使不知道int_member是否为“活动”成员,我也希望这是安全的,因为我看不出从char*int的静态转换应该失败或有问题的原因。 Is that correct? 那是对的吗?

If this implementation is unsafe, something like the following should be possible (using C-style casts in C, of course): 如果这个实现不安全的,像下面应(当然使用C风格的用C蒙上)是可能的:

return static_cast<void*>(*this) == static_cast<void*>(rhs);

...though of course if MyData is larger than the size of a pointer, you'd have to start messing around with sizeof to make this work. ...当然,如果MyData大于指针的大小,则必须开始弄乱sizeof才能使它工作。

Does anyone do this? 有人这样做吗? Is the first (simpler) implementation safe? 第一个(较简单的)实现安全吗? Is there any reason not to do it? 有什么理由这样做吗?

I think a better approach would be to wrap your union inside a class or struct with an enum field storing which was the last member accessed eg 我认为更好的方法是将您的联合包装在具有枚举字段存储的类或结构内,该枚举字段是最后访问的成员,例如

class MyData {
    enum {
        unintialized, int_member, ptr_member
    } last_member = unintialized;

    union {
        int int_member;
        char* ptr_member;
    } union_fields;

public:
    bool isInitialized() const
    {
        return last_member != unintialized;
    }
};

The in class initialization of last_member works if you have C++11 otherwise just initialize it in the default constructor. 如果您拥有C ++ 11,则last_member的类内初始化可以工作,否则只需在默认构造函数中对其进行初始化即可。

Create accessors for the two fields and set last_member accordingly, it would also be good to add checks in the accessor methods making sure only the "active member" can be accessed. 为这两个字段创建访问器并相应地设置last_member ,最好在访问器方法中添加检查以确保仅可以访问“活动成员”。

Of course it's unsafe. 当然是不安全的。

You can't assume that an int has the same size as a char * , for instance. 例如,您不能假定intchar *大小相同。 There might also be padding, which is often random in content. 也可能会有填充,填充通常是随机的。

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

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