RocketBall
RocketBall

Reputation: 45

Initializing union in a structure - c++

my code:

#include <iostream>

using namespace std;

struct widget
{
    char brand[20];
    int type;
    union id
    {
        long id_num;
        char id_char[20];
    }id_val;
};

int main()
{
    widget prize = 
    {"Rolls", 0, "A2X"};

    return 0;
}

The problem is with initialization "A2X" when initializing a union in a structure. Compiler doesn't know I want to choose second option with array of chars when I am passing "A2X", it's requiring long type. When I put

char id_char[20]

before

long id_num

everything is ok. But I want to know how to enforce compiler to accept "A2X" with char as the second option in union. Thank for your help.

Upvotes: 2

Views: 1165

Answers (2)

Petr Skocik
Petr Skocik

Reputation: 60058

This works with -std=c++11:

#include <cstring>
#include <stdexcept>

struct widget
{
    char brand[20];
    int type;
    union id
    {
        long id_num;
        char id_char[20];
    }id_val;
    widget(char const*Str, int Type, char const *Id);
};

widget::widget(char const*Str, int Type, char const *Id) 
{
    if (strlen(Str)+1 > sizeof brand)
        throw std::length_error{"brand too large"};
    memcpy(brand,Str,strlen(Str)+1);
    type = Type;
    if (strlen(Id)+1 > sizeof id_val.id_char)
        throw std::length_error{"id too large"};
    memcpy(id_val.id_char,Id,strlen(Id)+1);

}

int main()
{
    widget prize = {"Rolls", 0, "A2X"};

    return 0;
}

Upvotes: 0

eerorika
eerorika

Reputation: 238311

But I want to know how to enforce compiler to accept "A2X" with char as the second option in union.

You can use a constructor:

id(char const *id_char) {
    std::strcpy(this->id_char, id_char);
}

Alternatively you could use a widget constructor.

A drawback is that the compiler probably won't be able to warn you if you use a too large input string for initialization. The shown trivial constructor can be expanded with strlen to check overflow at runtime. I suggest throwing an exception if you choose to check.

Upvotes: 2

Related Questions