这个联合是否与严格别名规则兼容?

时间:2015-04-24 22:54:59

标签: c++11 unions strict-aliasing

如果您知道部件不重叠,是否可以使用工会的两个部分?就像在这个例子中一样,是否可以同时使用buf [31]和ps?

struct PtrSize {
  const char *data;
  size_t size;
};

class SmallStringOrNot {
  union {
    PtrSize  ps;
    char     buf[32];
  } pb;

public:
  bool IsSmallString() const {
    return pb.buf[31] != 0;
  }
  SmallStringOrNot(const char *str) {
    size_t len = strlen(str);
    if (len && len < 31) {
      memcpy(pb.buf, str, len);
      pb.buf[31] = len;
    } else {
      pb.ps.data = str;
      pb.ps.size = len;
      pb.buf[31] = 0;    // is this OK, accessing buf right after ps?
    }
  }
  PtrSize AsPtrSize() const {
    if (IsSmallString()) {
      return PtrSize{pb.buf, pb.buf[31]};
    } else {
      return pb.ps;
    }
  }
};

1 个答案:

答案 0 :(得分:0)

不幸的是,代码不正常:您至少没有&#34;未定义的行为&#34; -zone,因为在C ++中通过union访问char始终是合法的会员,但您不能保证通过修改buf[31]您不会改变ps.dataps.size。在128位机器中,你几乎肯定会这样做。

在更常见的体系结构上,您的代码应该没问题但是100%保证您应该参考编译器文档,因为size_t原则上可能大于void*。例如,即使在64位机器上,理论上你也可以拥有一个192位ps.size成员(与ps.data指针的64位相加会使PtrSize完全重叠缓冲液中。