[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