[Insight-developers] Link errors and itk::NumericTraits on Windows

Zachary Pincus zpincus at stanford.edu
Tue Apr 4 18:32:57 EDT 2006


Hi folks,

I've been tracking down a most annoying link problem with WrapITK on  
Windows. After much banging of my head, I think that it may be an  
actual issue with ITK itself.

Here is a brief description of what I think the problem is. On  
Windows, constants exported from DLLs need to be marked with  
ITKCommon_EXPORT. The NumericTraits<...>::Zero and ::One values are  
examples of such constants.

For each template instantiation, ITKCommon_EXPORT is provided for  
these values. However, in the template definition, there is no  
ITKCommon_EXPORT preceding these symbols. (I'm sure there is a very  
good reason for this.)

Here comes the tricky part: most classes that need NumericTraits will  
only #include "itkNumericTraits.h". In itkNumericTraits.h, however,  
traits for only the built in types are defined. Specializations for  
things like RGBPixel are declared in separate NumericTraits headers.

When an class (in my case, itk::ConstantBoundaryCondition) is  
instantiated with a pixel type like RGBPixel or CovariantVector, the  
NumericTraits specialization is not included, because the class did  
not #include "itkNumericTraitsRGBPixel.h", etc. Given that it is a  
generic class, #including a special NumericTraits header is at least  
easy for an author to forget, and at most counter to the principle of  
generic types.

Now, because the class has seen the generic traits definition from  
itkNumericTraits.h, the compiler can create a NumericTraits object  
for something like RGBPixel, so there won't be a compile error. Now  
we come full circle, however: this object's static members Zero and  
One will *not* be marked with ITKCommon_EXPORT, because the generic  
template definition does not mark Zero and One as ITKCommon_EXPORT.  
So on Windows, the linker can't find them in the ITKCommon DLL.

Thus, building a such a class (like  
itk::ConstantBoundaryCondition<itk::Image<itk::RGBPixel<unsigned  
char>, 2> > ) will result in really strange link errors on Windows,  
where the linker can't find the  
itk::NumericTraits<itk::RGBPixel<unsigned char> >::Zero symbol in the  
ITKCommon library, even though it is clearly defined in that library.

There are three possible solutions that I can think of:
(1) itkNumericTraits.h should #include all subsidiary NumericTraits  
headers. Then generic filters can #include just one generic numeric  
traits header, and be assured that regardless of what pixel types  
they are instantiated with, the right NumericTraits objects will be  
available.
(2) The NumericTraits class should declare that Zero and One are  
ITKCommon_EXPORT. I don't know if this will break things.
(3) Every class that might potentially be instantiated over RGB or  
vector pixels, etc, should #include all possible NumericTraits headers.

I think option 1 sounds the best. Are there any other approaches?  
Does anyone have any ideas as to what to do here?

Zach



More information about the Insight-developers mailing list