error#29 expected an expression

4.2k Views Asked by At

The following piece of code which is 2 dimensional array throws an error #29 expected an expression.

typedef  enum 
{
    BATTERY_POW = 0,
    USB_POW = 1,
    END_STATE = 2
} BMTState_e;   

typedef enum //event enums
{  
    NO_EVENT = 0,
    BOOT_EVENT =1,
    //I/O events
    POW_GOOD_LOW =2,
    POW_GOOD_HIGH = 3,
    VBUS_POW_LOW = 4,
    VBUS_POW_HIGH =5
}BMTEvent_e;

The structure is defined as

typedef struct  //state machine definition
{
    void (*funcPtr)();
    BMTState_e nextState;
}BMTAction_t;
BMTState_e BMTGlobal_State ; //global state

The function is defined as

void BMTTest()
{
 //do nothing for time being
}
BMTAction_t  action[END_STATE][END_EVENT]={
   [BATTERY_POW][NO_EVENT]    = {BMTTest,BATTERY_POW}
   [BATTERY_POW][BOOT_EVENT]    = {BMTTest,BATTERY_POW},
   [BATTERY_POW][POW_GOOD_LOW]  = {BMTTest,USB_POW},
   [BATTERY_POW][POW_GOOD_HIGH] = {BMTTest,BATTERY_POW}
   [BATTERY_POW][VBUS_POW_LOW]  = {BMTTest,BATTERY_POW},
   [BATTERY_POW][VBUS_POW_HIGH] = {BMTTest,USB_POW},
   [USB_POW][BOOT_EVENT]    = {BMTTest,USB_POW_}
   [USB_POW][BOOT_EVENT]    = {BMTTest,USB_POW},
   [USB_POW][POW_GOOD_LOW]  = {BMTTest,USB_POW},
   [USB_POW][POW_GOOD_HIGH] = {BMTTest,BATTERY_POW}
   [USB_POW][VBUS_POW_LOW]  = {BMTTest,BATTERY_POW},
   [USB_POW][VBUS_POW_HIGH] = {BMTTest,USB_POW}
}; 

void BMT_HandleEvent(BMTEvent_e event)
{
  BMTAction_t stAction;


   if(event != NO_EVENT)
   {
      stAction.funcPtr = action[BMTGlobal_State][event].funcPtr;
      stAction.nextState = action[BMTGlobal_State][event].nextState;
      printf("current State =%d, event = %d, nextState = %d",BMTGlobal_State, event,stAction.nextState );

      if(NULL!= stAction.funcPtr)
        stAction.funcPtr();
        BMTGlobal_State = stAction.nextState;
    }

}

int main()
{
BMTEvent_e = BOOT_EVENT;
if(retVal)
    {
    BMTGlobal_State = BATTERY_POW;
    }
else // PG is low so check VBUS signal 
    {
retVal = GPIO_Read_Pin(USB_VBUS_PWR_PIN);
if(retVal)
        {
        BMTGlobal_State = USB_POW;
        }
else
        {
        BMTGlobal_State = CRADLE_POW;
        }
    }
event = BOOT_EVENT;
while (1)
    {
    BMT_HandleEvent(event);
    } 
}

The idea is to execute the state machine based on the events received. The 2D array list the current state and all possible events for the state, once an event is received a function pointer will be invoked and the state will transition to the next state.

I am using MicroC/OS2 with GreenHills compiler/tools. I would appreciate your response.

I followed Keith's recommendation

BMTAction_t  action[END_STATE][END_EVENT] = {
                  {{NULL,BATTERY_POW}}, //0
                  {{BMTProcess_BatteryPowBoot,BATTERY_POW}},//   1
                  {{BMTProcess_PowGoodLow,BATTERY_POW}},//2
                  {{BMTProcess_PowGoodHigh,BATTERY_POW}}, //3
                  {{BMTProcess_VBUSPowerLow,BATTERY_POW}}, //4
                  {{BMTProcess_VBUSPowerHigh,BATTERY_POW}},//5 
};

The compiler gives error at line

"{{BMTProcess_PowGoodHigh,BATTERY_POW}}, //3" 
"error # 146 too many initializer values"
4

There are 4 best solutions below

10
Keith Thompson On

That's not the right syntax for designated initializer. You can only specify one index at a time.

I was incorrect; multiple designators are permitted. In fact, your code compiles without error using gcc -std=c99 -pedantic -Wall -Wextra after I add a few declarations.

typedef enum { BATTERY_POW, END_STATE } BMTState_e;
typedef enum { BOOT_EVENT, POW_GOOD_LOW, POW_GOOD_HIGH, END_EVENT } BMTEvent_e;

void BMTTest(void);

typedef struct  //state machine definition
{
    void (*funcPtr)();
    BMTState_e nextState;
}BMTAction_t;

BMTAction_t  action[END_STATE][END_EVENT]={
    [BATTERY_POW][BOOT_EVENT]    = {BMTTest,BATTERY_POW},
    [BATTERY_POW][POW_GOOD_LOW]  = {BMTTest,BATTERY_POW},
    [BATTERY_POW][POW_GOOD_HIGH] = {BMTTest,BATTERY_POW}
}; 

Most likely your compiler doesn't understand designated initializers. (They were added to the language by the 1999 standard, and even today not all compilers support them.)

If it doesn't, you'll need to remove the bracketed expressions (and make sure you have the elements in the right order). Probably something like:

BMTAction_t  action0[END_STATE][END_EVENT] = {
    {{ BMTTest, BATTERY_POW }},
    {{ BMTTest, BATTERY_POW }},
    {{ BMTTest, BATTERY_POW }}
};
0
user1867459 On

Keith answer helped me figure out the correct initialization. I had to list all the possible events and associated function pointer for a given state inside the {{ }}.

This is like to initializing elements of row[0][0] and row [0][1] I had to list all the elements inside the top level double curly braces something like

 { **{{**values/function/events associated with row [0][0],{values/function/events associated with row [0][1] }}, 
//now do the same for row 1. 
**{{**values/function/events associated with row [1][0],{values/function/events associated with row [1][1] **}}** }; //end of the array

BMTAction_t  action[END_STATE][END_EVENT] = {
                 //STATE = BATTERY_POW
                  {{NULL,BATTERY_POW}, //0
                  {BMTProcess_BatteryPowBoot,BATTERY_POW},//   1
                  {BMTProcess_PowGoodLow,BATTERY_POW},//2
                  {BMTProcess_PowGoodHigh,BATTERY_POW}, //3
                  {BMTProcess_VBUSPowerLow,BATTERY_POW}, //4
                  {BMTProcess_VBUSPowerHigh,BATTERY_POW}},//5 
                  //STATE = USB_POW
                  {{NULL,USB_POW}, //0
                  {BMTProcess_BatteryPowBoot,USB_POW},//   1
                  {BMTProcess_PowGoodLow,USB_POW},//2
                  {BMTProcess_PowGoodHigh,USB_POW}, //3
                  {BMTProcess_VBUSPowerLow,USB_POW}, //4
                  {BMTProcess_VBUSPowerHigh,USB_POW}}//5 
                };
0
Tim On

The initialization that you were using will work with the greenhills compiler if you use the -c99 option.

I had to make a few minor changes to your code to get it to compile:

  • Add the END_EVENT enum
  • Add some commas in between the items of the action declaration.
  • Fixed typo USB_POW_ to USB_POW

Here's the modified code:

#include <stdio.h>
typedef enum {
    BATTERY_POW = 0,
    USB_POW = 1,
    END_STATE = 2
} BMTState_e;

typedef enum {
    NO_EVENT = 0,
    BOOT_EVENT =1,
    //I/O events
    POW_GOOD_LOW =2,
    POW_GOOD_HIGH = 3,
    VBUS_POW_LOW = 4,
    VBUS_POW_HIGH =5,
    END_EVENT = 6

} BMTEvent_e;

typedef struct {
    void (*funcPtr)();
    BMTState_e nextState;
} BMTAction_t;

void BMTTest()
{
 //do nothing for time being
}
BMTAction_t  action[END_STATE][END_EVENT]={
[BATTERY_POW][NO_EVENT]    = {BMTTest,BATTERY_POW},
[BATTERY_POW][BOOT_EVENT]    = {BMTTest,BATTERY_POW},
[BATTERY_POW][POW_GOOD_LOW]  = {BMTTest,USB_POW},
[BATTERY_POW][POW_GOOD_HIGH] = {BMTTest,BATTERY_POW},
[BATTERY_POW][VBUS_POW_LOW]  = {BMTTest,BATTERY_POW},
[BATTERY_POW][VBUS_POW_HIGH] = {BMTTest,USB_POW},
[USB_POW][BOOT_EVENT]    = {BMTTest,USB_POW},
[USB_POW][BOOT_EVENT]    = {BMTTest,USB_POW},
[USB_POW][POW_GOOD_LOW]  = {BMTTest,USB_POW},
[USB_POW][POW_GOOD_HIGH] = {BMTTest,BATTERY_POW},
[USB_POW][VBUS_POW_LOW]  = {BMTTest,BATTERY_POW},
[USB_POW][VBUS_POW_HIGH] = {BMTTest,USB_POW}
};
int main()
{
    return 1;
}

Here's the compiler output without -c99:

$ ccppc test.c
"test.c", line 30: error #29: expected an expression
  [BATTERY_POW][NO_EVENT]    = {BMTTest,BATTERY_POW},
  ^

"test.c", line 31: error #29: expected an expression
  [BATTERY_POW][BOOT_EVENT]    = {BMTTest,BATTERY_POW},
  ^

"test.c", line 32: error #29: expected an expression
  [BATTERY_POW][POW_GOOD_LOW]  = {BMTTest,USB_POW},
  ^

"test.c", line 33: error #29: expected an expression
  [BATTERY_POW][POW_GOOD_HIGH] = {BMTTest,BATTERY_POW},
  ^

"test.c", line 34: error #29: expected an expression
  [BATTERY_POW][VBUS_POW_LOW]  = {BMTTest,BATTERY_POW},
  ^

"test.c", line 35: error #29: expected an expression
  [BATTERY_POW][VBUS_POW_HIGH] = {BMTTest,USB_POW},
  ^

"test.c", line 36: error #29: expected an expression
   [USB_POW][BOOT_EVENT]    = {BMTTest,USB_POW},
   ^

"test.c", line 37: error #29: expected an expression
  [USB_POW][BOOT_EVENT]    = {BMTTest,USB_POW},
  ^

"test.c", line 38: error #29: expected an expression
  [USB_POW][POW_GOOD_LOW]  = {BMTTest,USB_POW},
  ^

"test.c", line 39: error #29: expected an expression
  [USB_POW][POW_GOOD_HIGH] = {BMTTest,BATTERY_POW},
  ^

"test.c", line 40: error #29: expected an expression
  [USB_POW][VBUS_POW_LOW]  = {BMTTest,BATTERY_POW},
  ^

"test.c", line 41: error #29: expected an expression
  [USB_POW][VBUS_POW_HIGH] = {BMTTest,USB_POW}
  ^

And with -c99:

$ ccppc -c99 test.c
0
John Burger On

You do realise that your code includes the following:

   [USB_POW][BOOT_EVENT]    = {BMTTest,USB_POW_}
   [USB_POW][BOOT_EVENT]    = {BMTTest,USB_POW},

Even I'd be confused by that. Did you mean the first to be NO_EVENT?