Jump to content


Strange compile error in template class which occurs for certain function calls


3 replies to this topic

#1 Shree

    Member

  • Members
  • PipPip
  • 31 posts

Posted 28 October 2007 - 09:46 PM

I have a templated class (IsosurfaceOctreeVolume) which contains a pointer to another templated class (OctreeVolume), The start of the class definition is shown below:

   
    template <class T>
    class IsosurfaceOctreeVolume : public PrimitiveCommon
    {
        const OctreeVolume<T>* octdata;

For the 4 function calls made using this pointer below I get the following gcc compiler error "error: ISO C++ forbids comp arison between pointer and integer":

octdata->lookup_neighbor<0,0,1>(child_cell, offset, stop_depth, leaf_depth, index_trace);
octdata->lookup_neighbor<0,1,1>(child_cell, offset, stop_depth, leaf_depth, index_trace);
octdata->lookup_neighbor<1,0,1>(child_cell, offset, stop_depth, leaf_depth, index_trace);
octdata->lookup_neighbor<1,1,1>(child_cell, offset, stop_depth, leaf_depth, index_trace);

However, these 3 calls also using exactly the same pointer do not generate an error:

octdata->lookup_neighbor<1,1,0>(child_cell, offset, stop_depth, leaf_depth, index_trace);
octdata->lookup_neighbor<1,0,0>(child_cell, offset, stop_depth, leaf_depth, index_trace);
octdata->lookup_neighbor<0,1,0>(child_cell, offset, stop_depth, leaf_depth, index_trace);

Looking at the above 7 calls there seems to be a problem when the 3rd (last) template argument being passed to OctreeVolume::lookup_neighbor has the value 1 instead of 0.

The complete code for function lookup_neighbor (which is a member function of the templated class OctreeVolume) is listed below:

       
        template <typename T>
        template<bool CHECK_X, bool CHECK_Y, bool CHECK_Z>
        inline T OctreeVolume<T>::lookup_neighbor(Vec3i& cell, Vec3i& offset, int stop_depth, int depth, unsigned int* index_trace) const
        {
          Vec3i target_neighbor = cell + offset;
          int child_bit;
            
            //recurse up the tree until we find a parent that contains both cell and target_neighbor
          for(int up = depth; up >= 0; up--)
          {   
            child_bit = child_bit_depth[up];
                
            if (CHECK_X && CHECK_Y && CHECK_Z)
            {
              if ( ((target_neighbor.data[0] & child_bit) == (cell.data[0] & child_bit)) &&
                     ((target_neighbor.data[1] & child_bit) == (cell.data[1] & child_bit)) &&
                     ((target_neighbor.data[2] & child_bit) == (cell.data[2] & child_bit)) )
                return lookup_node(target_neighbor, stop_depth, up, index_trace[up]);
            }
            else if (CHECK_X && CHECK_Y)
            {
              if ( ((target_neighbor.data[0] & child_bit) == (cell.data[0] & child_bit)) &&
                     ((target_neighbor.data[1] & child_bit) == (cell.data[1] & child_bit)) )
                return lookup_node(target_neighbor, stop_depth, up, index_trace[up]);               
            }
            else if (CHECK_X && CHECK_Z)
            {
              if ( ((target_neighbor.data[0] & child_bit) == (cell.data[0] & child_bit)) &&
                     ((target_neighbor.data[2] & child_bit) == (cell.data[2] & child_bit)) )
                return lookup_node(target_neighbor, stop_depth, up, index_trace[up]);               
            }
            else if (CHECK_Y && CHECK_Z)
            {
              if ( ((target_neighbor.data[1] & child_bit) == (cell.data[1] & child_bit)) &&
                     ((target_neighbor.data[2] & child_bit) == (cell.data[2] & child_bit)) )
                return lookup_node(target_neighbor, stop_depth, up, index_trace[up]);               
            }
            else if (CHECK_X)
            {
              if ((target_neighbor.data[0] & child_bit) == (cell.data[0] & child_bit))
                return lookup_node(target_neighbor, stop_depth, up, index_trace[up]);
            }
            else if (CHECK_Y)
            {
              if ((target_neighbor.data[1] & child_bit) == (cell.data[1] & child_bit))
                return lookup_node(target_neighbor, stop_depth, up, index_trace[up]);
            }
            else if (CHECK_Z)
            {
              if ((target_neighbor.data[2] & child_bit) == (cell.data[2] & child_bit))
                return lookup_node(target_neighbor, stop_depth, up, index_trace[up]);
            }
          }
            
          child_bit = max_depth_bit;
          if (CHECK_X && CHECK_Y && CHECK_Z)
          {
            if ( ((target_neighbor.data[0] & child_bit) == (cell.data[0] & child_bit)) &&
                   ((target_neighbor.data[1] & child_bit) == (cell.data[1] & child_bit)) &&
                   ((target_neighbor.data[2] & child_bit) == (cell.data[2] & child_bit)) )
              return lookup_node(target_neighbor, stop_depth, 0, 0);
          }
          else if (CHECK_X && CHECK_Y)
          {
            if ( ((target_neighbor.data[0] & child_bit) == (cell.data[0] & child_bit)) &&
                   ((target_neighbor.data[1] & child_bit) == (cell.data[1] & child_bit)) )
              return lookup_node(target_neighbor, stop_depth, 0, 0);          
          }
          else if (CHECK_X && CHECK_Z)
          {
            if ( ((target_neighbor.data[0] & child_bit) == (cell.data[0] & child_bit)) &&
                   ((target_neighbor.data[2] & child_bit) == (cell.data[2] & child_bit)) )
              return lookup_node(target_neighbor, stop_depth, 0, 0);          
          }
          else if (CHECK_Y && CHECK_Z)
          {
            if ( ((target_neighbor.data[1] & child_bit) == (cell.data[1] & child_bit)) &&
                   ((target_neighbor.data[2] & child_bit) == (cell.data[2] & child_bit)) )
              return lookup_node(target_neighbor, stop_depth, 0, 0);              
          }
          else if (CHECK_X)
          {
            if ((target_neighbor.data[0] & child_bit) == (cell.data[0] & child_bit))
              return lookup_node(target_neighbor, stop_depth, 0, 0);
          }
          else if (CHECK_Y)
          {
            if ((target_neighbor.data[1] & child_bit) == (cell.data[1] & child_bit))
              return lookup_node(target_neighbor, stop_depth, 0, 0);
          }
          else if (CHECK_Z)
          {
            if ((target_neighbor.data[2] & child_bit) == (cell.data[2] & child_bit))
              return lookup_node(target_neighbor, stop_depth, 0, 0);
          }
                    
          return 0;
        }       

If I explicitly specify the type of the OctreeVolume (as shown below) then the error disappears:

namespace Manta
{
    template <class T>
    class IsosurfaceOctreeVolume : public PrimitiveCommon
    {
        const OctreeVolume<float>* octdata;

So declaring the pointer to be of type OctreeVolume<T> instead of OctreeVolume<float> or some other explicit type is somehow causing the above error. However, strangely it only affects 4 out of the 7 possible function calls.

Does anyone have any idea why this is happening and what the problem is?:wallbash:

#2 .oisyn

    DevMaster Staff

  • Moderators
  • 1810 posts

Posted 28 October 2007 - 11:06 PM

I suppose you're getting the error INSIDE the lookup_neighbor() function? See your compiler output for the exact details, and post them here.

Btw, you can severely reduce the code (and improve maintainability) in that function by using a single if.
if ( (!CHECK_X || (target_neighbor.data[0] & child_bit) == (cell.data[0] & child_bit)) &&
     (!CHECK_Y || (target_neighbor.data[1] & child_bit) == (cell.data[1] & child_bit)) &&
     (!CHECK_Z || (target_neighbor.data[2] & child_bit) == (cell.data[2] & child_bit)) )

C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#3 Shree

    Member

  • Members
  • PipPip
  • 31 posts

Posted 29 October 2007 - 11:08 AM

.oisyn said:

I suppose you're getting the error INSIDE the lookup_neighbor() function? See your compiler output for the exact details, and post them here.

My bad - sorry.

The error occurs when the lookup_neighbour function is called from within members functions of the IsoSurfaceOctreeVolume class.

Below is the actual compiler output (with errors) for one of these functions. (e.g IsoSurfaceOctreeVolume::single_traverse_leaf)

Quote

Building CXX object Model/CMakeFiles/Manta_Model.dir/Primitives/IsosurfaceOctreeVolume.o
/home/shree/dev/Manta/Model/Primitives/IsosurfaceOctreeVolume.h: In member function ‘bool Manta::IsosurfaceOctreeVolume<T>::single_traverse_leaf(Manta::RayPacket&, int, const Manta::Vector&, const Manta::Vector&, const Manta::Vector&, int, int, int, T, Manta::Vec3i&, unsigned int*, Manta::Vec3i&, float, float) const’:
/home/shree/dev/Manta/Model/Primitives/IsosurfaceOctreeVolume.h:753: error: ISO C++ forbids comparison between pointer and integer
/home/shree/dev/Manta/Model/Primitives/IsosurfaceOctreeVolume.h:765: error: ISO C++ forbids comparison between pointer and integer
/home/shree/dev/Manta/Model/Primitives/IsosurfaceOctreeVolume.h:777: error: ISO C++ forbids comparison between pointer and integer
/home/shree/dev/Manta/Model/Primitives/IsosurfaceOctreeVolume.h:813: error: ISO C++ forbids comparison between pointer and integer

The 4 calls to lookup_neighbour which generate these errors can be found in the section of the code (from IsoSurfaceOctreeVolume::single_traverse_leaf) below, immediately following the 4 comments :

//0,0,1
//0,1,1
//1,1,1
//1,0,1


#ifdef USE_OCTREE_DATA
                //use octree data
                  float rho[2][2][2];
                  T min_rho, max_rho, this_rho;
                  min_rho = max_rho = this_rho = scalar;
                  rho[0][0][0] = static_cast<float>(this_rho);
                  Vec3i offset(0,0,child_bit);
                                                
                //0,0,1
                  if (target_child & 1)
                  {
                    this_rho = octdata->lookup_neighbor<0,0,1>(child_cell, offset, stop_depth, leaf_depth, index_trace);
                    min_rho = MIN(min_rho, this_rho);
                    max_rho = MAX(max_rho, this_rho);
                  }
                  else
                    this_rho = scalar;
                  rho[0][0][1] = static_cast<float>(this_rho);
        
                //0,1,1
                  offset.data[1] = child_bit;
                  if (target_child & 3)
                  {
                    this_rho = octdata->lookup_neighbor<0,1,1>(child_cell, offset, stop_depth, leaf_depth, index_trace);
                    min_rho = MIN(min_rho, this_rho);
                    max_rho = MAX(max_rho, this_rho);
                  }
                  else
                    this_rho = scalar;
                  rho[0][1][1] = static_cast<float>(this_rho);
                
                //1,1,1
                  offset.data[0] = child_bit;
                  if (target_child & 7)
                  {
                    this_rho = octdata->lookup_neighbor<1,1,1>(child_cell, offset, stop_depth, leaf_depth, index_trace);
                    min_rho = MIN(min_rho, this_rho);
                    max_rho = MAX(max_rho, this_rho);
                  }
                  else
                    this_rho = scalar;
                  rho[1][1][1] = static_cast<float>(this_rho);    
                
                //1,1,0
                  offset.data[2] = 0;
                  if (target_child & 6)
                  {
                    this_rho = octdata->lookup_neighbor<1,1,0>(child_cell, offset, stop_depth, leaf_depth, index_trace);
                    min_rho = MIN(min_rho, this_rho);
                    max_rho = MAX(max_rho, this_rho);
                  }
                  else
                    this_rho = scalar;
                  rho[1][1][0] = static_cast<float>(this_rho);
                
                //1,0,0
                  offset.data[1] = 0;
                  if (target_child & 4)
                  {
                    this_rho = octdata->lookup_neighbor<1,0,0>(child_cell, offset, stop_depth, leaf_depth, index_trace);
                    min_rho = MIN(min_rho, this_rho);
                    max_rho = MAX(max_rho, this_rho);
                  }
                  else
                    this_rho = scalar;  
                  rho[1][0][0] = static_cast<float>(this_rho);
                
                //1,0,1
                  offset.data[2] = child_bit;
                  if (target_child & 5)
                  {
                    this_rho = octdata->lookup_neighbor<1,0,1>(child_cell, offset, stop_depth, leaf_depth, index_trace);
                    min_rho = MIN(min_rho, this_rho);
                    max_rho = MAX(max_rho, this_rho);
                  }
                  else
                    this_rho = scalar;
                  rho[1][0][1] = static_cast<float>(this_rho);    
            
                //0,1,0
                  offset.data[0] = 0;
                  offset.data[1] = child_bit;
                  offset.data[2] = 0;
                  if (target_child & 2)
                  {
                    this_rho = octdata->lookup_neighbor<0,1,0>(child_cell, offset, stop_depth, leaf_depth, index_trace);
                    min_rho = MIN(min_rho, this_rho);
                    max_rho = MAX(max_rho, this_rho);
                  }
                  else
                    this_rho = scalar;
                  rho[0][1][0] = static_cast<float>(this_rho);
#else 


#4 Shree

    Member

  • Members
  • PipPip
  • 31 posts

Posted 29 October 2007 - 11:09 AM

.oisyn said:

Btw, you can severely reduce the code (and improve maintainability) in that function by using a single if.
if ( (!CHECK_X || (target_neighbor.data[0] & child_bit) == (cell.data[0] & child_bit)) &&

     (!CHECK_Y || (target_neighbor.data[1] & child_bit) == (cell.data[1] & child_bit)) &&

     (!CHECK_Z || (target_neighbor.data[2] & child_bit) == (cell.data[2] & child_bit)) )

Thanks for this! I will do so :yes:





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users