[Insight-users] Borland 6 Build error

Luis Ibanez luis.ibanez@kitware.com
Sat, 23 Nov 2002 11:32:53 -0500


Hi John,

It actually looks like a compiler problem, since the
same code is passing fine in other compilers, including
Borland 5.5.

Borland seem to be very picky with integers as template
arguments. In particular when the arguments are used to
define new types that are also templated.

In this case, for example, the return type is one of
the usual suspects.  Slice() returns a "SliceRegion"
which is an ImageRegion of dimension= N-1.  The type
of "SliceRegion" is declared in line 85 of itkImageRegion.h


typedef ImageRegion<itkGetStaticConstMacro(SliceDimension)> SliceRegion;


Note that SliceRegion is an ImageRegion templated over
"SliceDimension" and SliceDimension = ImageDimension -1 .
This is then, a recursive definition, since every ImageRegion
will have an internal ImageRegion of dimension-1.

An attempt to stop the recursion in dimension=0 is made in
the declaration of "SliceDimension" in line 69 of the same
file:


itkStaticConstMacro(SliceDimension, unsigned int,
                       (VImageDimension - (VImageDimension > 1)));

It may be that Borland 6 is not interpreting this statement
correctly and the resulting definintion of the SliceDimension
and SliceRegion are being inconsistent between the .h and .txx
files.

Note that the statement is counting on a true boolean to be
represented as = "1" (while in principle we should only count
on it being different from zero), and it is counting on the
actual evaluation being performed during the compilation of the
class.


I'll suggest you to try a simple example of the equivalent
recursion. The typical case is the factorial template metaprogram:

http://osl.iu.edu/~tveldhui/papers/Template-Metaprograms/meta-art.html

A bit modified below:

======================================================

#include <iostream>

template<int N>
class Factorial {
public:
     enum { value = N * Factorial<N-1>::value };
     Factorial()
     {
       std::cout << "Factorial of " << N << " = " << value << endl;
     }
};

class Factorial<1> {
public:
     enum { value = 1 };
};


main()
{
   Factorial<5> f;
   return 0;
}

======================================================

Could you please try if Borland 6 is capable of
manging this template recursion ?

If it does, we can start working form here to identify
where things are being different from the code in ITK.

Note that the use of the "enum" in the Factorial class
may have to be replaced with

    static const unsigned int  value = N * Factorial<N-1>::value;

Since Borland prefer the static integers ivars to enums.
Other compilers don't like the initialization of static
on the headers, and that's the reason why this is done
in ITK with a selective macro defined in itkMacro.h

For Borland the code should probably be

======================================================

#include <iostream>

template<int N>
class Factorial {
public:
     static const unsigned int  value = N * Factorial<N-1>::value;
     Factorial()
     {
       std::cout << "Factorial of " << N << " = " << value << endl;
     }
};

class Factorial<1> {
public:
     static const unsigned int value = 1;
};


main()
{
   Factorial<5> f;
   return 0;
}

======================================================

Please let us know what you find.



   Thanks


    Luis


==========================

John Biddiscombe wrote:

> In a spare moment trying to get ITK built with BCB6 I ran into this error
> 
> D:\Insight\Code\Numerics\FEM\itkFEMSolver.cxx:
> Error E2316 D:\Insight\Code\Common\itkImageRegion.txx 177:
> 'ImageRegion<VImageDimension>::Slice(const unsigned long) const'
> is not a member of 'ImageRegion<VImageDimension>'
> 
> I can only assume a compiler glitch, but can anyone suggest a workaround or
> reason why this error is being thrown up. The code in question is below, it
> doesn't like the declaration (There are many more very similar errors so
> finding a workaround would help no end.)
> 
> JB
> 
> template<unsigned int VImageDimension>
> typename ImageRegion<VImageDimension>::SliceRegion
> ImageRegion<VImageDimension>
> ::Slice(const unsigned long dim) const
> {
>   Index<SliceDimension> sliceIndex;
>   Size<SliceDimension> sliceSize;
> 
>   unsigned int ii = 0;
>   for (unsigned int i=0; i < VImageDimension; i++)
>     {
>     if (i != dim)
>       {
>       sliceIndex[ii] = m_Index[i];
>       sliceSize[ii] = m_Size[i];
>       ++ii;
>       }
>     }
> 
>   return ImageRegion<SliceDimension>(sliceIndex, sliceSize);
> }
> 
> 
> _______________________________________________
> Insight-users mailing list
> Insight-users@public.kitware.com
> http://public.kitware.com/mailman/listinfo/insight-users
> 
>