Link to home
Start Free TrialLog in
Avatar of openujs
openujs

asked on

C++ Weird behavior: Compile error (C2027)

I am getting error
error C2027: use of undefined type 'Phil' at line:

int leftStatus = p->pPhil->getStatusForLeftNeighbor(p->m_ID);
pPhil of type is member for Thread class. Why would it complain about that line? Both Phil and Thread class are defined in same file. So there is no need for include or extern.


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#define MAX_PHIL 5
#define DEBUG 1
#define TIMEFRAME 200

enum { STATE_THINKING = 100, STATE_EATING };


//Global Event handel
static HANDLE gEvent;

///////////////////////////////////////////////////////////////////////////////
class Phil;
class Thread
{

public:
      Thread()
      {
            leftChop = rightChop = -1;

            HANDLE hnd = CreateThread(NULL,0,ThreadProc,this,0,&m_ThreadID);
            if(hnd == NULL)
            {
            }

            m_State = STATE_THINKING;
            pPhil = 0;
      }
      ~Thread();

      static DWORD WINAPI ThreadProc(LPVOID lpParameter)
      {
            Thread*p = (Thread*)lpParameter;
            if(p == 0) return 0;

            p->m_ID++;
#if DEBUG
            
            printf("Thread %d is running. Status= %s.\n", p->m_ThreadID, p->getStatus(p->m_State));
#endif


            char buf[40];
            time_t oldtime, newtime= 0;
            struct tm  *ts;
            oldtime = time(0);

            ts = localtime(&oldtime);
            strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", ts);
              printf("Starting time = %d, %s\n\n", &oldtime, buf);
                  

            for(;;)  
            {
                  time_t ntime = time(0);

                  int leftStatus = p->pPhil->getStatusForLeftNeighbor(p->m_ID);
                  int rightStatus =  p->pPhil->getStatusForRightNeighbor(p->m_ID);

                  if(leftStatus == STATE_THINKING
                        && rightStatus == STATE_THINKING )
                  {
                        p->m_State = STATE_EATING;
            #if DEBUG
                        printf("%d thread ID (%d) is EATING.\n", p->m_ThreadID, p->m_ID);
            #endif
                  }

                  if( WaitForSingleObject(gEvent,5000) == WAIT_OBJECT_0)break;
            }
            
            printf("Thread %d is exiting.\n", p->m_ThreadID);

            //return 0;      
      };

      static DWORD m_ID;
      DWORD m_ThreadID;
      int m_State;
      Phil* pPhil;
      

      int leftChop, rightChop;

      void assignChops(int threadID, int id, int size)
      {
            if( id < size ) rightChop = id+1;
            else rightChop = 0;

            if( id > 0 ) leftChop = id-1;
            else leftChop = size;

            if( id == 0 ) leftChop = size - 1;
            if( id == size - 1) rightChop = 0;

            printf("%d thread ID (%d) is assigned left chop = %d and right chop = %d.\n", threadID, id, leftChop, rightChop);
      };

      char* getStatus(int state)
      {
            char* s;
            switch(state)
            {
                  case(STATE_THINKING):
                        s = "STATE_THINKING";
                        break;
                  case(STATE_EATING):
                        s = "STATE_EATING";
                        break;
            }
            return s;
      }
};

class Phil
{
public:
      Phil()
      {
            gEvent = CreateEvent(NULL,true,false,NULL);
      }

      void process(void)
      {
            char buf[40];
            time_t oldtime, newtime= 0;
            struct tm  *ts;
            oldtime = time(0);

            ts = localtime(&oldtime);
            strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", ts);
              printf("Starting time = %d, %s\n\n", &oldtime, buf);
                  

            for(;;)  
            {
                  time_t ntime = time(0);

                  if(ntime > oldtime + TIMEFRAME)
                  {
                        SetEvent(gEvent);
                        break;
                  }

                  if(ntime > newtime)
                  {
                        newtime = ntime;
                        ts = localtime(&ntime);
                        strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", ts);
                          printf("Current time = %d, %s\n", newtime, buf);
                  }
            }
            
      }
      
      void initiate()
      {
            for(int i =0;i<MAX_PHIL; i++)
            {
                  m_pThreadArray[i] = new Thread();
                  m_pThreadArray[i]->pPhil = (Phil*)this;
                  m_pThreadArray[i]->assignChops(m_pThreadArray[i]->m_ThreadID, m_pThreadArray[i]->m_ID, MAX_PHIL);
            }
      }

      void clean()
      {
            for(int i =0;i<MAX_PHIL; i++)
            {
                  delete m_pThreadArray[i];
            }
      }
      DWORD getStatusForLeftNeighbor(int id)
      {
            if(id == 0)
                  return m_pThreadArray[MAX_PHIL-1]->m_State;
            else
                  return m_pThreadArray[id-1]->m_State;

      };
      
      DWORD getStatusForRightNeighbor(int id)
      {
            if(id == MAX_PHIL-1)
                  return m_pThreadArray[0]->m_State;
            else
                  return m_pThreadArray[id+1]->m_State;
      };

      Thread* m_pThreadArray[MAX_PHIL];
};



DWORD Thread::m_ID = 0;

//////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
      Phil Aphil;
      Aphil.initiate();
      Aphil.process();

          return 1;
}


/////////////////////////////////////////////
by the way where is zone C++. C++ should have its own zone.
Avatar of evilrix
evilrix
Flag of United Kingdom of Great Britain and Northern Ireland image

you use Phil in your thread class yet you've only provided a forward definition first. Move the definition of Phil class before thread class.
Avatar of openujs
openujs

ASKER

evilrix,

Well if you do that, then I get - error C2027: use of undefined type 'Thread'. It is more like Chicken and egg problem.
You'll have to move all the member function definitions out of the class definition - preferably in their own .cpp file.
//// instead of :

class Foo {
  public :
    void bar() {
      // implementation here
    }
};


//// do this :

/* -- foo.h -- */

#ifndef FOO_H
#define FOO_H

class Foo {
  public :
    void bar();
};

#endif /* FOO_H */


/* -- foo.cpp -- */

#include "foo.h"

void Foo::bar() {
  // implementation here
}

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of evilrix
evilrix
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial