error: aggregate value used where an integer was expected

Discussion in 'C Programming' started by aleksa, Feb 18, 2012.

  1. aleksa

    aleksa Guest

    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"
    aleksa, Feb 18, 2012
    #1
    1. Advertising

  2. aleksa

    Shao Miller Guest

    On 2/18/2012 12:35, aleksa wrote:
    > 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."
    Shao Miller, Feb 18, 2012
    #2
    1. Advertising

  3. On Sat, 18 Feb 2012 09:35:04 -0800 (PST), aleksa <>
    wrote:

    >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.

    --
    Remove del for email
    Barry Schwarz, Feb 18, 2012
    #3
  4. aleksa

    aleksa Guest

    > 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
    aleksa, Feb 18, 2012
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Olaf Kittelmann

    J2EE aggregate entity - Value Disassembler

    Olaf Kittelmann, Dec 2, 2003, in forum: Java
    Replies:
    0
    Views:
    372
    Olaf Kittelmann
    Dec 2, 2003
  2. Charles Jamieson

    non-aggregate error

    Charles Jamieson, Jul 13, 2004, in forum: C++
    Replies:
    6
    Views:
    476
    Old Wolf
    Jul 14, 2004
  3. koperenkogel
    Replies:
    3
    Views:
    2,686
    =?ISO-8859-1?Q?Ney_Andr=E9_de_Mello_Zunino?=
    Mar 24, 2005
  4. Neviton
    Replies:
    14
    Views:
    9,360
    James Kanze
    Sep 19, 2007
  5. Replies:
    3
    Views:
    113
Loading...

Share This Page