0%

匿名联合体和匿名结构体

编译出错:

main.c:9:16: error: ‘struct channel::<unnamed union>::dvb’ invalid; an anonymous union can only have non-static data members [-fpermissive]
         struct dvb {
                ^~~

source code

#include <string.h>

struct channel {
    int id;
    unsigned int services_num;
    int *services;
    unsigned char delivery;
    union {
        struct dvb {
            int onid;
            int tsid;
            int sid;
        } dvb;

        struct ott {
            int backendid;
            int channelid;
        } ott;
    };
} ch;

int main(void)
{
    memset(&ch, 0, sizeof(struct channel));
}

编译

$ gcc main.c
$ g++ main.c
main.c:9:16: error: ‘struct channel::<unnamed union>::dvb’ invalid; an anonymous union can only have non-static data members [-fpermissive]
         struct dvb {
                ^~~
main.c:15:16: error: ‘struct channel::<unnamed union>::ott’ invalid; an anonymous union can only have non-static data members [-fpermissive]
         struct ott {
                ^~~
$ g++ -fpermissive main.c
main.c:9:16: warning: ‘struct channel::<unnamed union>::dvb’ invalid; an anonymous union can only have non-static data members [-fpermissive]
         struct dvb {
                ^~~
main.c:15:16: warning: ‘struct channel::<unnamed union>::ott’ invalid; an anonymous union can only have non-static data members [-fpermissive]
         struct ott {
                ^~~

solutions

I

增加编译选项 -fpermissive

$ gcc main.c
$ g++ main.c
main.c:10:16: warning: ‘struct channel::<unnamed union>::dvb’ invalid; an anonymous union can only have non-static data members [-fpermissive]
         struct dvb {
                ^~~
main.c:16:16: warning: ‘struct channel::<unnamed union>::ott’ invalid; an anonymous union can only have non-static data members [-fpermissive]
         struct ott {
                ^~~

II

增加 union 成员 u

struct channel {
    int id;
    unsigned int services_num;
    int *services;
    unsigned char delivery;
    union {
        struct dvb {
            int onid;
            int tsid;
            int sid;
        } dvb;

        struct ott {
            int backendid;
            int channelid;
        } ott;
    } u;
} ch;
$ gcc main.c
$ g++ main.c

III

修改匿名 union 内部结构体为匿名

struct channel {
    int id;
    unsigned int services_num;
    int *services;
    unsigned char delivery;
    union {
        struct {
            int onid;
            int tsid;
            int sid;
        };

        struct {
            int backendid;
            int channelid;
        };
    };
} ch;

或者

struct channel {
    int id;
    unsigned int services_num;
    int *services;
    unsigned char delivery;
    union {
        struct {
            int onid;
            int tsid;
            int sid;
        } dvb;

        struct {
            int backendid;
            int channelid;
        } ott;
    };
} ch;
$ gcc main.c
$ g++ main.c

IV

修改为如下同样存在问题,这种方式是一种错误,定义了 struct dvb 类型,但是没有定义属于该类型的任何对象

struct channel {
    int id;
    unsigned int services_num;
    int *services;
    unsigned char delivery;
    union {
        struct dvb {
            int onid;
            int tsid;
            int sid;
        };

        struct ott {
            int backendid;
            int channelid;
        };
    };
} ch;
$ gcc main.c
main.c:13:10: warning: declaration does not declare anything
         };
          ^
main.c:18:10: warning: declaration does not declare anything
         };
          ^
$ g++ main.c
main.c:9:16: error: ‘struct channel::<unnamed union>::dvb’ invalid; an anonymous union can only have non-static data members [-fpermissive]
         struct dvb {
                ^~~
main.c:15:16: error: ‘struct channel::<unnamed union>::ott’ invalid; an anonymous union can only have non-static data members [-fpermissive]
         struct ott {
                ^~~

C++ union 特点

C++ 联合体中不能包含非基本类型成员变量,原因好像是因为非基本类型存在构造函数(包括默认构造函数)为了避免多层嵌套后结构的安全性

C++ 中 union 里面需要的成员需要共享内存,因此静态引用都不能用,因为他们不可能共享内存

Ref

  1. 例解 C 语言中的匿名联合体和匿名结构体
  2. anonymous union can only have non-static data members GCC c
  3. anonymous union can only have non-static data members GCC c++
  4. Why does C++ disallow anonymous structs?
  5. Anonymous union and struct
  6. C++对C语言的结构、联合、枚举 这3种数据类型进行了扩展