error: aggregate value used where an integer was expected

A

aleksa

typedef struct { // 16 bits, one WORD
unsigned short B4:4; // (using GCC)
unsigned short B9:9;
unsigned short B1:1;
unsigned short B2:2;
} S1;

typedef struct {
S1 q1, q2;
} S2;

static S2 table[2]= {
{{1,1,1,1}, {1,1,1,1}}, // just test values
{{1,1,1,1}, {1,1,1,1}}
};

unsigned short getq1 (int i)
{
unsigned short bit16;

// ERROR HERE
// aggregate value used where an integer was expected
bit16 = (unsigned short) table.q1;

return bit16;
}


Someone has already suggested using unions,

typedef struct {
unsigned short B4:4;
unsigned short B9:9;
unsigned short B1:1;
unsigned short B2:2;
} BitField;

typedef union {
BitField bits;
unsigned short all;
} S1;

typedef struct {
S1 q1, q2;
} S2;

but I don't know how to initialize the table:

static S2 table[2]= {
{{1,1,1,1}, {1,1,1,1}}, // just test values
{{1,1,1,1}, {1,1,1,1}}
};

That doesn't work anymore, i get
"missing braces around initializer"
 
S

Shao Miller

typedef struct { // 16 bits, one WORD
unsigned short B4:4; // (using GCC)
unsigned short B9:9;
unsigned short B1:1;
unsigned short B2:2;
} S1;

That might end up as 16 bits on a particular C implementation, but
that's not guaranteed for all implementations.
typedef struct {
S1 q1, q2;
} S2;

static S2 table[2]= {
{{1,1,1,1}, {1,1,1,1}}, // just test values
{{1,1,1,1}, {1,1,1,1}}
};

unsigned short getq1 (int i)
{
unsigned short bit16;

// ERROR HERE
// aggregate value used where an integer was expected
bit16 = (unsigned short) table.q1;

/*
* Assuming alignment and object representation
* is what you're expecting...
*/
bit16 = *((unsigned short *) &table.q1);
return bit16;
}


[...]

You could make a proper function which builds an 'unsigned short' from
the members of an 'S1'.

unsigned short ushort_from_s1(S1 value) {
return (
(value.B4 << 12) |
(value.B9 << 3) |
(value.B1 << 2) |
(value.B2)
);
}

This would make the "low" members the "most significant bits."
 
B

Barry Schwarz

typedef struct { // 16 bits, one WORD
unsigned short B4:4; // (using GCC)
unsigned short B9:9;
unsigned short B1:1;
unsigned short B2:2;
} S1;

typedef struct {
S1 q1, q2;
} S2;

static S2 table[2]= {
{{1,1,1,1}, {1,1,1,1}}, // just test values
{{1,1,1,1}, {1,1,1,1}}
};

unsigned short getq1 (int i)
{
unsigned short bit16;

// ERROR HERE
// aggregate value used where an integer was expected
bit16 = (unsigned short) table.q1;


table is an array of S2.
table is a particular S2 in that array.
table.q1 is the first S1 in that S2.

S1 is a struct. Structures and arrays are aggregates by definition.

You need table.q1.B4 or whichever B? you are interested in.

The cast should be unnecessary since all the scalar objects have the
same type.
return bit16;
}


Someone has already suggested using unions,

typedef struct {
unsigned short B4:4;
unsigned short B9:9;
unsigned short B1:1;
unsigned short B2:2;
} BitField;

typedef union {
BitField bits;
unsigned short all;
} S1;

From this I gather you don't care about the individual bit fields but
really want the 16 bit composite value.
typedef struct {
S1 q1, q2;
} S2;

but I don't know how to initialize the table:

static S2 table[2]= {
{{1,1,1,1}, {1,1,1,1}}, // just test values
{{1,1,1,1}, {1,1,1,1}}
};

That doesn't work anymore, i get
"missing braces around initializer"

My compiler doesn't produce this error and accepts the definition
int i = table[0].q1.all;
in main(). However -

The outer pair of braces (lines 1 and 4) simply bound the
initialization text.

The beginning and ending braces on line 2 specify that the data
applies to table[0]. The ones on line 3 specify table[1].

table[0] consists of 2 objects, each an S1.

The first pair of inner braces on line 2 bound the initialization for
table[0].q1. q is a union so you are attempting to initialize the
first member. That member is an aggregate of type BitField. To
initialize this aggregate, you need another pair of braces. Try

static S2 table[2]= {
{{{1,1,1,1}}, {{1,1,1,1}}}, // just test values
{{{1,1,1,1}}, {{1,1,1,1}}}
};

which my system also accepts. Both version print 24593 (0x6011) for i
which does not match my expectations, even for a little endian system.
 
A

aleksa

The first pair of inner braces on line 2 bound the initialization for
table[0].q1.  q is a union so you are attempting to initialize the
first member.  That member is an aggregate of type BitField.  To
initialize this aggregate, you need another pair of braces.  Try

    static S2 table[2]= {
        {{{1,1,1,1}}, {{1,1,1,1}}},   // just test values
        {{{1,1,1,1}}, {{1,1,1,1}}}
    };

which my system also accepts.

Tried it, works fine... and I understand why. Thank you!
Are you a professor, are you teaching other people?
You are good..
Both version print 24593 (0x6011) for i
which does not match my expectations, even for a little endian system.

0x6011 is what I would expect.

From MSB to LSB, there are 2, 1, 9 and 4 bits:

00 0 000000000 0000, and all are initialized to 1:
01 1 000000001 0001

concatenating we get:
0110000000010001

splitting into nibbles we get:
0110_0000_0001_0001

which is 0x6011
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top