Announcement

Collapse
No announcement yet.

DEBUG: Odd behaviour of Assertions

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • DEBUG: Odd behaviour of Assertions

    While I was readding some of the slic functions of the patch I noticed that this code gives more debug assertions regarding Diplomacy personalities strings:

    Code:
    SFN_ERROR Slic_TileHasImprovement::Call(SlicArgList *args)
    {
    	if(args->m_numArgs != 2)
    		return SFN_ERROR_NUM_ARGS;
    
    	MapPoint pos;
    	if(!args->GetPos(0, pos))
    		return SFN_ERROR_TYPE_ARGS;
    
    	sint32 imp;
    	if(!args->GetInt(1, imp))
    		return SFN_ERROR_TYPE_ARGS;
    
    	m_result.m_int = 0;
    	Cell *cell = g_theWorld->GetCell(pos);
    	for(sint32 i = 0; i < cell->GetNumDBImprovements(); i++) {
    
    		if(imp == cell->GetDBImprovement(i)){
    			m_result.m_int = 1;
    			return SFN_ERROR_OK;
    		}
    	}
    	m_result.m_int = 0;
    	return SFN_ERROR_OK;
    }
    But this code is fine:

    Code:
    SFN_ERROR Slic_TileHasImprovement::Call(SlicArgList *args)
    {
    	if(args->m_numArgs != 2)
    		return SFN_ERROR_NUM_ARGS;
    
    	MapPoint pos;
    	if(!args->GetPos(0, pos))
    		return SFN_ERROR_TYPE_ARGS;
    
    	sint32 imp;
    	if(!args->GetInt(1, imp))
    		return SFN_ERROR_TYPE_ARGS;
    
    	m_result.m_int = 0;
    	Cell *cell = g_theWorld->GetCell(pos);
    	for(sint32 i = 0; i < cell->GetNumDBImprovements(); i++) {
    
    		if(imp == cell->GetDBImprovement(i)){
    			m_result.m_int = 1;
    			return SFN_ERROR_OK;
    		}
    	}
    	return SFN_ERROR_OK;
    }
    The only difference Between these two pieces of code is that the line m_result.m_int = 0; is placed before the for loop in the second piece of code instead afterwards.

    -Martin
    Civ2 military advisor: "No complaints, Sir!"

  • #2
    Well, what kind of asserts is it giving you?
    Administrator of WePlayCiv -- Civ5 Info Centre | Forum | Gallery

    Comment


    • #3
      It is in diplomat.cpp located line 661:

      Code:
      void Diplomat::SetPersonalityName(const char *personality_name) {
      	m_personalityName = string(personality_name);
      
      	
      	sint32 index;
      	bool found = g_thePersonalityDB->GetNamedItem(personality_name, index);
      	Assert(found);
      	if (found)
      		m_personality = g_thePersonalityDB->Get(index);
      	
      }
      Assert(found); fails but only if I put the line:
      m_result.m_int = 0;
      after the for loop. Otherwise no problem and that is what I don't understand, why the order of a piece of code does matter even if it is not called.

      -Martin
      Civ2 military advisor: "No complaints, Sir!"

      Comment


      • #4
        That is indeed very strange... The only explanation I can think of is that the memory which did hold the integer is now being used for something else which is not correctly initialized, but that seems far fetched.

        Comment


        • #5
          The assignment is not made after in the assert case, but both before and after. Is there some provision for putting the same value back in? What if you put twice m_result.m_int = 0; before the loop?
          (You know that putting it after is useless anyway I bet)
          Clash of Civilization team member
          (a civ-like game whose goal is low micromanagement and good AI)
          web site http://clash.apolyton.net/frame/index.shtml and forum here on apolyton)

          Comment


          • #6
            I haven't seen the actual code (apart from what was posted in this thread), but I'm wondering how you knew to fix it like this? What's the connection between Slic_TileHasImprovement::Call and Diplomat::SetPersonalityName?

            Comment


            • #7
              Origianlly posted by Leland
              I haven't seen the actual code (apart from what was posted in this thread), but I'm wondering how you knew to fix it like this? What's the connection between Slic_TileHasImprovement::Call and Diplomat::SetPersonalityName?
              I have no idea what the connection between Slic_TileHasImprovement::Call and Diplomat::SetPersonalityName is, especial if I consider that I added the Slic_TileHasImprovement::Call on my own. So the only connection are the additional asserts.

              Getting to know to fix like this is easy, just take a look on the other slic functions and you see that the m_result.m_int = 0; comes before all the other code in those slic functions.

              Origianlly posted by LDiCesare
              The assignment is not made after in the assert case, but both before and after. Is there some provision for putting the same value back in? What if you put twice m_result.m_int = 0; before the loop?
              (You know that putting it after is useless anyway I bet)
              I don't see any sense in putting it twice before the loop as once is enough. And it is not useless to put it afterwards the loop as it returns the right value, it just gives me an additional assert.

              Origianlly posted by J Bytheway
              That is indeed very strange... The only explanation I can think of is that the memory which did hold the integer is now being used for something else which is not correctly initialized, but that seems far fetched.
              I think it is not too far fetched, actual the only explanation I can come up now. In my Java course we did something with threads. Threads are a way to simulate parallel computation on a single processor, every window program is full of threads. For instance the program must be react on mouse clicks while it is computing something else in the background. Basicly one thread is active while the other threads are passive, in the active thread values of objects can be changed or objects can be deleted/created. So if you delete an objet somewhere that is needed in another thread or don't create it than you have a problem.

              OK to make it short, threads are necessary in complex programs, but there are some problems like death lock and live lock and instability. Death lock is when all your theads are waiting from stuff from each other to continue their computation. And a live lock is when the threads are waiting for more processor capacity to compute more expensive stuff but do easy stuff while they are waiting. In a live lock you see the program hang but the processor load goes to the limit, while at a death lock the processor does nothing. About instability is to mention that your program can run on the one computer very stable and on the other computer very instable, or a very random crashing behaviour that for instance depends on the internal state of the computer e.g. random number generator. I know not a very good example, because it looks very random and it is indeed very random.

              Well that text became longer than I thought, but that is so far all I know about, we got not know more about it as it would have been to much for a Java course, especially if you consider that there is a whole lecture about this topic.

              -Martin
              Civ2 military advisor: "No complaints, Sir!"

              Comment

              Working...
              X