[Insight-developers] fixed Visual C++ ICE on NeighborhoodOperator

Brad King brad.king@kitware.com
Fri, 23 Feb 2001 17:35:33 -0500 (EST)


Hello, all:

Will asked me to take a look at the INTERNAL COMPILER ERROR that
Visual C++ has been producing when building Josh's
itk::NeighborhoodOperator class.  I have no explanation for why this
happens, other than a bug in the compiler, but I managed to reduce the
problem to a simple example.

The first of the following four examples cause the problem, but the other
three don't, despite very minor differences.

---------------------------------------------------------------------------
// This version results in the INTERNAL COMPILER ERROR.
namespace N { class A {}; }
class B { void f(N::A); };
template <int V> class C {};  // ICE here, on the ">" after "int V".
---------------------------------------------------------------------------
// Template parameter of class C a typename instead of value.
namespace N { class A {}; }
class B { void f(N::A); };
template <typename T> class C {};
---------------------------------------------------------------------------
// Inline implementation of function B::f.
namespace N { class A {}; }
class B { void f(N::A) {} };
template <int V> class C {};
---------------------------------------------------------------------------
// Function B::f's parameter is not a name from another namespace.
class A {};
class B { void f(A); };
template <int V> class C {};
---------------------------------------------------------------------------

This problem existed in the NeighborhoodOperator and several other
classes. The reason was that the protected coefficient manipulation
functions used "std::vector<TPixel>" as an argument type:

template< class TPixel, unsigned int VDimension >
class ITK_EXPORT NeighborhoodOperator : public Neighborhood<TPixel,
VDimension>
{
...
protected:
...
 virtual void FillCenteredDirectional(const std::vector<TPixel> &);
...
};

This corresponds to the "void f(N::A)" part of the above example
(N = std, A = vector<TPixel>).

Then, the .txx part of the source is included right after the class
definition (since ITK_MANUAL_INSTANTIATION is not defined).  This
begins with the code:

template<class TPixel, unsigned int VDimension>
void
NeighborhoodOperator<TPixel, VDimension>
::CreateDirectional()
{
...
}

The template<...> line includes an argument with an integral type.  This
corresponds to the "template <int V> class C{};" part of the example
(int V = unsigned int VDimension).

I have gone through all the classes in Code/Common that have this problem
and added "typedef std::vector<TPixel> CoefficientVector;" so that
the functions could use the name "CoefficientVector", which solves the
INTERNAL COMPILER ERROR problem and is more descriptive anyway.

These changes were checked in a few minutes ago.  If anyone encounters
this problem again, refer to this email for the solution.

-Brad