2017-04-14 71 views
0

我在我自己的滚动结构来表示颜色的过程,这就是我想出了:这种类型的狡猾法律和安全吗?

struct Color { 
    typedef uint8_t color_t; 

    union { 
     struct { 
      color_t red, green, blue, alpha; 
     }; 
     struct { 
      color_t x, y, z, w; 
     } 
     std::array<color_t, 4> _data; 
    }; 

    /*...*/ 
}; 

这样做是为了简化编写索引代码的行为。就像,例如,operator[]代码是这样写的:

//I haven't written bounds-checking yet. 
constexpr color_t & operator[](size_t i) { 
    return _data[i]; 
} 

constexpr color_t operator[](size_t i) const { 
    return _data[i]; 
} 

我的理解是,这应该是安全的(实际上,这个代码编译和运行,因为我希望它),但在此我我实际上是正确的假设,还是我可能冒着未定义的行为写这样的代码?

+0

我相信我在过去的日子里看到过几个问题(也许有人会找到重复的,因为我太懒惰了)。如果不是'union',你会更安全一些,因为你会引用数组的元素。 –

+0

该结构的源文件可能会很小,那么为什么不直接写出更大的代码而不是使用联合(哪一个应该尽可能避免)呢?另外,我可以问你为什么定义operator []吗?渠道的顺序不会自动给出,这意味着没有人有责任维护它。如果您需要在某个文件中编写颜色,请将该责任交给颜色结构本身或写入该图像类的图像类,然后使用使命令清晰的代码,如“<<红色<<绿色<<蓝色'。 – Aziuth

+1

除此之外:你不需要实现边界检查自己,只需使用['std :: array :: at()'](http://en.cppreference.com/w/cpp/container/array/at) –

回答

3

从不活跃的联盟成员读取是未定义的行为。

一次只有一个工会成员可以活跃。

前缀的布局兼容性是一个例外,但阵列不符合标准下具有多个成员的任何struct

可能会生成合法有效的operator[](size_t),但不能通过union

+0

如果'uint8_t'是一个字符类型,是否有任何理由允许通过字符指针读取和写入任何类型的PODS的规则不适用于通过数组访问? – supercat