LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   C compiling error: expected expression before ‘{’ token (https://www.linuxquestions.org/questions/programming-9/c-compiling-error-expected-expression-before-%91%7B%92-token-715616/)

CoderMan 03-30-2009 07:06 PM

C compiling error: expected expression before ‘{’ token
 
Hi. I have a compiling error which doesn't seem to want to go away. I suppose I could try to do it another way, but it seems really annoying that it is not working and I'm not sure why.

The code is compiled with gcc. I'm just compiling the object code now - not yet linking it into the program. Here is the compiler error:

Code:

bash-3.00$ gcc -c menu_browser.c
menu_browser.c: In function ‘create_menu_browser_ctrl’:
menu_browser.c:10: error: expected expression before ‘{’ token

Here is the offending source file, menu_browser.c:

Code:

#include <stdlib.h>
#include <pthread.h>
#include "menu_data.h"
#include "menu_browser.h"
#include "disp_thread_modes.h"

struct Menu_Browser_Ctrl * create_menu_browser_ctrl(MenuItem_List_Bundle * menuitem_list_bundle)
{
  struct Menu_Browser_Ctrl * menu_browser_ctrl = malloc(sizeof(struct Menu_Browser_Ctrl));
  menu_browser_ctrl->mode_h = PTHREAD_MUTEX_INITIALIZER;
  menu_browser_ctrl->mode = th_m_dead;
  menu_browser_ctrl->menuitem_list_bundle = menuitem_list_bundle;
  return menu_browser_ctrl;
}

If I comment out the line with "PTHREAD_MUTEX..." in it, the source compiles fine, so I'm (wildly) guessing that this has something to do with the PTHREAD_MUTEX_INITIALIZER macro.

Here is menu_browser.h:

Code:

#ifndef _MENU_BROWSER_
#define _MENU_BROWSER_

#include <pthread.h>
#include "menu_data.h"

struct Menu_Browser_Ctrl {
  pthread_mutex_t mode_h;
  char mode;
  struct m_i_l_b * menuitem_list_bundle;
};

struct Menu_Browser_Ctrl * create_menu_browser_ctrl(MenuItem_List_Bundle * menuitem_list_bundle);

#endif

"menu_data.h" is kind of long, but it provides typedef struct
MenuItem_List_Bundle. "disp_thread_modes.h" simply provides a few constants.

CoderMan 03-30-2009 07:42 PM

Solved... I think
 
I think I figured out what was wrong. The problem is that PTHREAD_MUTEX_INITIALIZER is, well, an initializer... and I was trying to use it differently.

Here is the definition from pthread.h:

Code:

# define PTHREAD_MUTEX_INITIALIZER \
  { { 0, 0, 0, 0, 0, 0, { 0, 0 } } }

So I adjusted the code to look like so:
Code:

struct Menu_Browser_Ctrl * create_menu_browser_ctrl(MenuItem_List_Bundle * menuitem_list_bundle)
{
  struct Menu_Browser_Ctrl * menu_browser_ctrl = malloc(sizeof(struct Menu_Browser_Ctrl));
  pthread_mutex_t mode_h = PTHREAD_MUTEX_INITIALIZER;
  menu_browser_ctrl->mode_h = mode_h;
  menu_browser_ctrl->mode = th_m_dead;
  menu_browser_ctrl->menuitem_list_bundle = menuitem_list_bundle;
  return menu_browser_ctrl;
}

And this seems to compile. I wanted to just have a default initialization inside the struct itself, but that didn't seem to compile. (Is that allowed?)

wje_lq 03-30-2009 08:42 PM

As you probably already realize, this has nothing to do with whether it's in a struct.

It has everything to do with the difference between initializing a variable as you declare it and assigning to it after it's been declared.

To see the difference in action, run this shell script:
Code:

cat > 1.c <<EOD; cat -n 1.c; gcc -Wall -pthread 1.c -o 1
#include <stdlib.h>
#include <pthread.h>

int main(void)
{
  pthread_mutex_t yyy=PTHREAD_MUTEX_INITIALIZER;
  yyy=PTHREAD_MUTEX_INITIALIZER;

  return 0;

} /* main() */

The first use of PTHREAD_MUTEX_INITIALIZER is correct; the second is not. When I ran this, I got the following output:
Code:

    1  #include <stdlib.h>
    2  #include <pthread.h>
    3
    4  int main(void)
    5  {
    6    pthread_mutex_t yyy=PTHREAD_MUTEX_INITIALIZER;
    7    yyy=PTHREAD_MUTEX_INITIALIZER;
    8
    9    return 0;
    10
    11  } /* main() */
1.c: In function 'main':
1.c:7: error: expected expression before '{' token

This has nothing to do with POSIX threads particularly, and everything to do with initializing structs.

If you wish to initialize a mutex at a point other than when you declare it, a good way is to use pthread_mutex_init().

Hope this helps.

icarus127 03-31-2009 04:31 PM

Quote:

Originally Posted by CoderMan (Post 3493121)
Code:

struct Menu_Browser_Ctrl * create_menu_browser_ctrl(MenuItem_List_Bundle * menuitem_list_bundle)
{
  struct Menu_Browser_Ctrl * menu_browser_ctrl = malloc(sizeof(struct Menu_Browser_Ctrl));
  pthread_mutex_t mode_h = PTHREAD_MUTEX_INITIALIZER;
  menu_browser_ctrl->mode_h = mode_h;
  menu_browser_ctrl->mode = th_m_dead;
  menu_browser_ctrl->menuitem_list_bundle = menuitem_list_bundle;
  return menu_browser_ctrl;
}

And this seems to compile. I wanted to just have a default initialization inside the struct itself, but that didn't seem to compile. (Is that allowed?)

The trouble with this solution is the copy of the mutex. According to the pthread man pages operations performed on a copied mutex are undefined. In order to safely initialize a non-static mutex you must use pthread_mutex_init() as wje_lq suggested.


All times are GMT -5. The time now is 04:20 PM.