2

I've been browsing stackoverflow concerning the problem of initialising a union in a struct but I didn't manage to get it right.

Here is my struct

typedef struct dc_netif_filter {
    unsigned char filter_type;  
    union {
        uint32_t itf_nb;
        char * buf; 
    } value;
} dc_netif_filter_t;  

In my code, i have tried to use :

dc_netif_filter_t netif = {DC_NETIF_SELECT_NAME,{{0, "tun"}}};  

which gives error: braces around scalar initializer for type ‘uint32_t’

and

dc_netif_filter_t netif = {DC_NETIF_SELECT_NAME,{0, "tun"}};  

which gives error: too many initializers for ‘dc_netif_filter::< anonymous union>’

How do i declare such a dc_netif_filter_t ?

I'm using g++ on ubuntu. Note that the dc_netif_filter_t isn't a struct that I can modify as it comes from a third party project.

**EDIT : as I've been explained, i can only initialise one field. The problem is that with

dc_netif_filter_t netif = {DC_NETIF_SELECT_NAME,"tun0"}; 

I get a conversion error : invalid conversion from ‘const char*’ to ‘uint32_t

Thanks

9
  • 3
    You only initialise one member of a union. Commented Apr 16, 2012 at 13:22
  • You don't want to initialize all the members of the union; how about: dc_netif_filter_t netif = {DC_NETIF_SELECT_NAME, "tun"}; Commented Apr 16, 2012 at 13:24
  • then how do i set buf to "tun" and then 0 to itf_nb ? Commented Apr 16, 2012 at 13:25
  • 1
    You don't. Unions aren't structures. BTW, your code looks like C, not C++. Commented Apr 16, 2012 at 13:26
  • @trojanfoe i get " error: invalid conversion from ‘const char*’ to ‘uint32_t’ " Commented Apr 16, 2012 at 13:26

3 Answers 3

7

As the compiler says, too many initializers for ‘dc_netif_filter::< anonymous union>’.

Initialize only one field, not both.

Use the name of the field to initialize it properly:

dc_netif_filter_t netif = {DC_NETIF_SELECT_NAME, { buf: "tun0" }}; 
Sign up to request clarification or add additional context in comments.

4 Comments

If I initialize only the field i'm interested in with what is my edit (see the OP edited) I get a conversion error
I believe that this is a non-standard g++ extension.
@Nick I have no idea. It's called Designated Initializers in ISO C99. Probably the same in C++ but I'm not certain.
@Soohjun Thank you, the edited version works ! You sir, deserve some love ;)
2

It looks like you are trying to initialize your structure to indicate that the buf member is to be used, and that the value of that buf should be "tun". Since C++ before C++11 lacks designated initializers, you cannot do it with an initializer: only the first field of the union can be initialized, so you need to do your assignment in code:

static get_dc_netif_filter_t() {
    static c_netif_filter_t netif = {DC_NETIF_SELECT_NAME, {0}};
    if (netif.value.itf_nb == 0) {
        netif.value.buf = "tun";
    }
    return netif;
}

C++11 lets you do it like this:

dc_netif_filter_t netif = {DC_NETIF_SELECT_NAME, { .buf = "tun"}};

3 Comments

I get : expected primary-expression before ‘.’ token Is there a compiler option I am missing ?
@djfoxmccloud try -std=c++11
This is incorrect. Designated Initializers are not in C++11. They are currently proposed for C++20 (see open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0329r4.pdf). However, they do seem to currently work in GCC, Clang as well as MSVC.
1

This works under g++ 4.7.0:

dc_netif_filter_t netif = {DC_NETIF_SELECT_NAME, {.buf="tun"}};

Although designated initializers are supposed to be C only, not C++! Maybe it's a GNU extension?

I guess the best (most compatible) way is to assign the members after initialization:

dc_netif_filter_t netif;
netif.itf_nb = DC_NETIF_SELECT_NAME;
netif.value.buf = "TUN";

3 Comments

I get : expected primary-expression before ‘.’ token Is there a compiler option I am missing ?
No, I used no command line options. I guess it must be dependent on compiler version; as I say it's not supposed to work in C++ anyway.
I understand that it is not "supposed to work in C++", the thing is that I need to compile this code "as is" ;) With g++ 4.4.3 it doesn't work, i'll try upgrading

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.