C++ 如何使用嵌套在没有名称的结构中的c union

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13624760/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 17:33:25  来源:igfitidea点击:

How to use c union nested in struct with no name

c++cunionsanonymous

提问by zwx

I'm working on the so called Hotspot open source project, and looking at the implementation I found a nasty nested union in struct looking like that:

我正在研究所谓的 Hotspot 开源项目,在查看实现时,我在 struct 中发现了一个令人讨厌的嵌套联合,如下所示:

typedef struct RC_model_t_st
{
    union
    {
        struct block_model_t_st *block;
        struct grid_model_t_st *grid;
    };
    /* block model or grid model    */
    int type;
    thermal_config_t *config;
}RC_model_t;

As far as I'm aware in C/C++ that union is unaccesible. So how someone can make use of union declared in such manner and for what purpose?

据我所知,在 C/C++ 中,联合是不可访问的。那么有人如何使用以这种方式声明的 union 以及出于什么目的?

Thanks!

谢谢!

回答by Angew is no longer proud of SO

This is an anonymous union.In C++, as per [class.union], paragraph 5:

这是一个匿名的工会。在 C++ 中,根据 [class.union],第 5 段:

For the purpose of name lookup, after the anonymous union definition, the members of the anonymous union are considered to have been defined in the scope in which the anonymous union is declared

出于名称查找的目的,在匿名联合定义之后,匿名联合的成员被认为是在声明匿名联合的范围内定义的

This means you can access its members as if they were members of RC_model_t_st.

这意味着您可以像访问RC_model_t_st.

回答by Atmocreations

Without being sure and without having tried:

没有确定也没有尝试过:

The union itself is not accessible, but it's members are.

工会本身是不可访问的,但它的成员可以。

Therefore you should be able to do refer to obj.blockand obj.grid

因此,您应该能够参考obj.blockobj.grid

回答by Phani

This code here (https://gist.github.com/klange/4042963) shows how to access anonymous unions inside struct. You just access the members of nested union as if they are members of the struct.

此处的代码 ( https://gist.github.com/klange/4042963) 显示了如何访问结构体中的匿名联合。您只需访问嵌套联合的成员,就好像它们是结构的成员一样。

typedef struct {
    union {
        char * company;
        char * school;
        char * project;
    };
    union {
        char * location;
        char * url;
    };
    union {
        char * title;
        char * program;
    };

    time_t started;
    time_t left;

    char * description[];
} thing_t;

typedef thing_t job_t;

job_t yelp = {
    .company  = "Yelp, Inc.",
    .location = "San Francisco, CA",
    .title    = "Software Engineer, i18n",
    .started  = 1339977600,
    .left     = CURRENT,
    .description = {
        "Developed several internal tools and libraries",
        "Provided critical input and design work for Yelp's launch in Japan",
        NULL
    }
};

回答by Richard Chambers

To elaborate on the answer provided by Angew quoting the standard concerning anonymous unions and structs, I thought to provide an sample of C source code with the output generated by that sample showing how values are allocated within a structand a unioncomposed of structand unioncomponents.

为了详细说明通过引用Angew有关匿名联合和结构的标准所提供的答案,我认为提供的C源代码与由该样品显示生成的输出值是如何内的分配的样品struct和一个union组成structunion组分。

The standard quoted by Angew is:

Angew引用的标准是:

For the purpose of name lookup, after the anonymous union definition, the members of the anonymous union are considered to have been defined in the scope in which the anonymous union is declared.

出于名称查找的目的,在匿名联合定义之后,匿名联合的成员被认为已在声明匿名联合的范围内定义。

The source code of a structcomposed of named and anonymous structs and unions looks like the following. This is using Visual Studio 2005 and the #pragma (pack, 1)is used to align everything on a charboundary in order for there to be no memory holes. There is also a simple C Preprocessor macro defined to make the output more legible and easier to code.

struct由命名和匿名结构体和联合体组成的源代码如下所示。这是使用 Visual Studio 2005,#pragma (pack, 1)用于对齐char边界上的所有内容,以免出现内存漏洞。还定义了一个简单的 C 预处理器宏,以使输出更清晰且更易于编码。

typedef unsigned char UCHAR;

// use of Microsoft Visual Studio pragma to force char alignment for the struct.
#pragma pack(push, 1)
const struct {
    union {
        const UCHAR myArray[];  // this array shares memory with struct following
        struct {
            const UCHAR iOne;
            const UCHAR iTwo;
            const UCHAR iThree;
        };  // anonymous struct accessed by specifying Things.
    };      // anonymous union accessed by specifying Things.
//  const UCHAR myArray[];   // will cause error - "error C2020: 'myArray' : 'struct' member redefinition"
    union {
        const UCHAR myArray[];  // this array shares memory with struct following
        struct {
            const UCHAR iOne;
            const UCHAR iTwo;
            const UCHAR iThree;
        } s;    // named struct accessed by specifying Things.u.s
    } u;        // named union accessed by specifying Things.u
} Things = {1, 2, 4, 8, 9, 10, 22, 23, 24, 25};
#pragma pack(pop)

// a little helper macro to make the output easier to code.
#define PRINTF_VAL(x) printf ("%s %d \n", #x, x)

int itSelf (UCHAR iMask)
{
    int iMatch = -1;

    int jj = 0;
    jj = Things.myArray[0]; PRINTF_VAL(Things.myArray[0]);
    jj = Things.myArray[1]; PRINTF_VAL(Things.myArray[1]);
    jj = Things.myArray[2]; PRINTF_VAL(Things.myArray[2]);
    jj = Things.myArray[3]; PRINTF_VAL(Things.myArray[3]);
    jj = Things.myArray[4]; PRINTF_VAL(Things.myArray[4]);
    jj = Things.iOne; PRINTF_VAL(Things.iOne);
    jj = Things.iTwo; PRINTF_VAL(Things.iTwo);
    jj = Things.iThree; PRINTF_VAL(Things.iThree);

    jj = Things.u.myArray[0]; PRINTF_VAL(Things.u.myArray[0]);
    jj = Things.u.myArray[1]; PRINTF_VAL(Things.u.myArray[1]);
    jj = Things.u.myArray[2]; PRINTF_VAL(Things.u.myArray[2]);
    jj = Things.u.myArray[3]; PRINTF_VAL(Things.u.myArray[3]);
    jj = Things.u.myArray[4]; PRINTF_VAL(Things.u.myArray[4]);
    jj = Things.u.s.iOne; PRINTF_VAL(Things.u.s.iOne);
    jj = Things.u.s.iTwo; PRINTF_VAL(Things.u.s.iTwo);
    jj = Things.u.s.iThree; PRINTF_VAL(Things.u.s.iThree);

    return iMatch + 1;
}

The output generated by this function looks like:

此函数生成的输出如下所示:

Things.myArray[0] 1
Things.myArray[1] 2
Things.myArray[2] 4
Things.myArray[3] 8
Things.myArray[4] 9
Things.iOne 1
Things.iTwo 2
Things.iThree 4
Things.u.myArray[0] 8
Things.u.myArray[1] 9
Things.u.myArray[2] 10
Things.u.myArray[3] 22
Things.u.myArray[4] 23
Things.u.s.iOne 8
Things.u.s.iTwo 9
Things.u.s.iThree 10

The output shows the overlap between the various components of the main struct, Thingscaused by the use of unions. You can also see how the components of the anonymous structand unionare referenced versus those components of the named structand union.

输出显示在主的各种部件之间的重叠structThings因使用工会。您还可以看到匿名struct和的组件如何union被引用与命名struct和的组件相比union

Also just for fun I tried adding an array definition of const UCHAR myArray[];after the anonymous unioncontaining const UCHAR myArray[];to see what would happen. The compiler complained with an error of error C2020: 'myArray' : 'struct' member redefinition. The addition is commented out in the structdefinition of Thingsabove. However since the second use of const UCHAR myArray[];is in a named unionthe compile works because second use is accessed by specifying the name of the union.

也只是为了好玩,我尝试const UCHAR myArray[];在匿名union包含之后添加一个数组定义,const UCHAR myArray[];看看会发生什么。编译器抱怨错误error C2020: 'myArray' : 'struct' member redefinition。添加在上面的struct定义中被注释掉了Things。然而,由于第二次使用const UCHAR myArray[];是在一个命名union的编译工作,因为第二次使用是通过指定联合的名称来访问的。

回答by sciarp

Names declared in an anonymous union are used directly, like nonmember variables. A good reason to do this is to save memory.

在匿名联合中声明的名称可以直接使用,就像非成员变量一样。这样做的一个很好的理由是节省内存。

#include <iostream>

int main(int argc, char **argv) {
   union {
      double first;
      double second;
   };

   first = 10.001;
   second = 3.141592;
   std::cout << first << " " << second << std::endl;

   first = 10.002;
   std::cout << first << " " << second << std::endl;
}

回答by akp

first of all i want to say that A union, is a collection of variables of different types, just like a structure. However, with unions, you can only store information in one field at any one time.

首先我想说A union,是不同类型变量的集合,就像一个结构体。但是,对于联合,您一次只能将信息存储在一个字段中。

The unions are basically used for memory saving & it's size is equal to the largest member of the union.

联合基本上用于节省内存,它的大小等于联合的最大成员。

And for accessing the data fields of a union, use the dot operator(.) just as you would for a structure and explained by @Atmocreations. When a value is assigned to one member, the other member(s) get whipped out since they share the same memory.

并且要访问联合的数据字段,请使用点运算符 (.),就像对结构一样,并由 @Atmocreations 解释。当一个值被分配给一个成员时,其他成员会被抽走,因为他们共享相同的内存。

as an example where the unions may be useful is

作为工会可能有用的一个例子是

union time    
        {
        long time_in_sec;
        double time_in_mili_sec;
        }mytime;

.... The union above could be used to either store the current time (in seconds) to hold time accurate to a second. Or it could be used to hold time accurate to a millisecond. Presumably there are times when you would want one or the other, but not both. This declaration should look familiar. It is the same as a struct definition, but with the keyword union instead of struct.

.... 上面的联合可用于存储当前时间(以秒为单位)以保持时间精确到一秒。或者它可以用来保持精确到毫秒的时间。据推测,有时您会想要其中一个,但不会两者都想要。这个声明应该看起来很熟悉。它与 struct 定义相同,但使用关键字 union 而不是 struct。

for more info http://msdn.microsoft.com/en-us/library/5dxy4b7b(v=vs.80).aspx

更多信息http://msdn.microsoft.com/en-us/library/5dxy4b7b(v=vs.80).aspx