代码之家  ›  专栏  ›  技术社区  ›  user2138149

我认为我的工会可能会产生不明确的行为。

  •  0
  • user2138149  · 技术社区  · 7 年前

    uint8_t 或作为单独的rgb元素。(我认为这可能是工会为数不多的用途之一。)

    像这样的:

    union PixelRGB
    {
        uint8_t array[3];
        struct rgb
        {
            uint8_t b;
            uint8_t g;
            uint8_t r;
        };
    };
    

    几分钟前我问了一个问题,关于一个单独的问题,但被告知我的工会可能会产生UB。

    this 它确实表明,如果我从一个不是最后一个被写的成员那里读到,那么结果就是UB。。。

    我的问题是为什么?

    b = array[0]
    g = array[1]
    r = array[2]
    

    也就是说,这些变量在内存中占用的字节(空间/位置/地址)完全相同,因此我假设

    g = 0xff;
    

    array[1] 成为 0xff .

    为了论证:C++ 14

    重复的问题不是重复的:链接的问题问的是一个联合中的两个结构是否是UB-不是我在这里问的那样。

    3 回复  |  直到 7 年前
        1
  •  4
  •   YSC    7 年前

    我已经读过了,它确实表明,如果我从一个不是最后一个要写的成员读,那么结果是UB。。。

    我的问题是为什么?

    1个 . 该标准有时强加给我们(C++开发人员)规则,允许实现(编译器)忽略边缘情况,并允许它们对标称情况进行优化。这就是这样的规则。

    一些编译器可能会像您所期望的那样构建二进制文件。有些可能会产生崩溃的可执行文件。有些人可能会做任何介于两者之间或看似随机的事情。 未定义的行为未定义 2个 .


    [class.union]/1

    [basic.life]/7

    程序有未定义的行为,如果 :

    • glvalue用于访问对象,或

    为了更容易为人类解析,使用以下上下文:

    union { unsigned a; char b[sizeof(unsigned)]; } u;
    u.a = 0;       // (1)
    (void) u.b[0]; // (2) UB
    

    在线标记 (1) u.a 现在是 u . 每 [类联合]/1 u.b 活跃。

    这意味着在线标记 (2) [基本生活]/7 .


    [defns.undefined]

    未定义的行为

        2
  •  2
  •   Jack Aidley    7 年前

    这是未定义的行为,在标准中明确如此。你不能在一个写一个联盟,并在另一个阅读(ExpApple应用),并获得在C++中定义的行为。

        3
  •  0
  •   user2138149    7 年前

    显然,这个假设可能依赖于编译器。因此,我发现这是另一种解决方案:

    class PixelRGB
    {
    
        public:
    
        unsigned char array[3];
        unsigned char &r;
        unsigned char &g;
        unsigned char &b;
    
        PixelRGB()
            : r{array[2]}
            , g{array[1]}
            , b{array[0]}
        {
        }
    }
    

    unsigned char[] 然后只用这个来操纵,这就是我的目的。