[Insight-users] Explicit Instantiation question

Rupert Brooks rupe.brooks at gmail.com
Mon Nov 5 14:27:54 EST 2007


Brad,

Thanks for the thorough reply.   Basically im glad to hear that im not
too far off base.  I explored my g++ errors a bit more.  Heres a
minimal example that demonstrates the error.

This is a pretty wierd error, so im not really expecting anyone to
have a fix - I  just report it here to complete the conversation.   I
dont really have the option of upgrading g++ for various reasons, so i
will probably simply move affected classes out of my set of explicitly
compiled ones and carry on.  Maybe next time i build ITK i'll try the
Explicit build option

Its worth mentioning that this g++ might be strange.  Its on a
cluster, and so by default set up to compile and link in MPI
libraries.  I've tried to eliminate that default and thus any
interference that may cause, but who knows, there could be a
configuration issue i am unaware of.

Like I said - i dont really expect an answer to this one.  Just reporting....

Cheers,

Rupert B.

Minimal code example:
The following two C++ files with a CMake entry like

ADD_EXECUTABLE(ExplicitInstantiationTest
tests/ExplicitInstantiationTest.cxx
tests/ExplicitInstantiationTestSupport.cxx  )
TARGET_LINK_LIBRARIES(ExplicitInstantiationTest ${ITKLIBS})

will compile and run without problems in Visual C++ 2003 and gcc 4.0.3
on Ubuntu Linux.  However, with this gcc

[rbrooks at hn Release]$ g++ -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --enable-shared --enable-threads=posix
--disable-checking --with-system-zlib --enable-__cxa_atexit
--host=i386-redhat-linux
Thread model: posix
gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
[rbrooks at hn Release]$

compiling with the -O3 option causes the error below, which does NOT
occur with -O2 or no -O option

--------------------------------- ExplicitInstantiationTest.cxx
---------------------------------
#define ITK_MANUAL_INSTANTIATION
#include "itkImage.h"
#include "itkCheckerBoardImageFilter.h"
#include <iostream>

typedef itk::Image<float,2> ImageType;
typedef itk::CheckerBoardImageFilter<ImageType> FilterType;
extern template class itk::Image<float,2>;
extern template class itk::CheckerBoardImageFilter<ImageType>;

int main() {
  FilterType::Pointer filter=FilterType::New();
  std::cout<<"I declared a "<<filter->GetNameOfClass()<<std::endl;
}

--------------------------------- ExplicitInstantiationTestSupport.cxx
---------------------------------
#include "itkImage.h"
#include "itkCheckerBoardImageFilter.h"
#include <iostream>

typedef itk::Image<float,2> ImageType;
typedef itk::CheckerBoardImageFilter<ImageType> FilterType;
template class  itk::Image<float,2>;
template class  itk::CheckerBoardImageFilter<ImageType>;

--------------------------------- the error ---------------------------------

/home/rbrooks/src/Insight/Code/BasicFilters/itkCheckerBoardImageFilter.h: In
   static member function `static
   itk::SmartPointer<itk::CheckerBoardImageFilter<TImage> >
   itk::CheckerBoardImageFilter<TImage>::New() [with TImage =
ImageType]':/home/rbrooks/src/Insight/Code/BasicFilters/itkCheckerBoardImageFilter.h:56:
  instantiated from
`itk::CheckerBoardImageFilter<TImage>::CheckerBoardImageFilter() [with
TImage = ImageType]'/home/rbrooks/src/Insight/Code/BasicFilters/itkCheckerBoardImageFilter.h:56:
  instantiated from `static
itk::SmartPointer<itk::CheckerBoardImageFilter<TImage> >
itk::CheckerBoardImageFilter<TImage>::New() [with TImage =
ImageType]'/home/rbrooks/registration/src/tests/ExplicitInstantiationTest.cxx:12:
  instantiated from
here/home/rbrooks/src/Insight/Code/BasicFilters/itkCheckerBoardImageFilter.h:56:
explicit
   instantiation of `
   itk::CheckerBoardImageFilter<TImage>::CheckerBoardImageFilter() [with TImage
   = ImageType]' but no definition available
/home/rbrooks/src/Insight/Code/BasicFilters/itkCheckerBoardImageFilter.h: At
   global scope:/home/rbrooks/src/Insight/Code/BasicFilters/itkCheckerBoardImageFilter.h:
In instantiation of
`itk::CheckerBoardImageFilter<TImage>::CheckerBoardImageFilter() [with
TImage = ImageType]':/home/rbrooks/src/Insight/Code/BasicFilters/itkCheckerBoardImageFilter.h:56:
  instantiated from `static
itk::SmartPointer<itk::CheckerBoardImageFilter<TImage> >
itk::CheckerBoardImageFilter<TImage>::New() [with TImage =
ImageType]'/home/rbrooks/registration/src/tests/ExplicitInstantiationTest.cxx:12:
  instantiated from
here/home/rbrooks/src/Insight/Code/BasicFilters/itkCheckerBoardImageFilter.h:56:
explicit
   instantiation of `
   itk::CheckerBoardImageFilter<TImage>::CheckerBoardImageFilter() [with TImage
   = ImageType]' but no definition
available/home/rbrooks/src/Insight/Code/BasicFilters/itkCheckerBoardImageFilter.h:
In instantiation of
`itk::CheckerBoardImageFilter<TImage>::CheckerBoardImageFilter() [with
TImage = ImageType]':/home/rbrooks/src/Insight/Code/BasicFilters/itkCheckerBoardImageFilter.h:56:
  instantiated from `static
itk::SmartPointer<itk::CheckerBoardImageFilter<TImage> >
itk::CheckerBoardImageFilter<TImage>::New() [with TImage =
ImageType]'/home/rbrooks/registration/src/tests/ExplicitInstantiationTest.cxx:12:
  instantiated from
here/home/rbrooks/src/Insight/Code/BasicFilters/itkCheckerBoardImageFilter.h:56:
explicit
   instantiation of `
   itk::CheckerBoardImageFilter<TImage>::CheckerBoardImageFilter() [with TImage
   = ImageType]' but no definition
available/usr/include/c++/3.2.2/iostream: In instantiation of
`itk::CheckerBoardImageFilter<TImage>::CheckerBoardImageFilter() [with
TImage = ImageType]':/usr/include/c++/3.2.2/iostream:56:
instantiated from `static
itk::SmartPointer<itk::CheckerBoardImageFilter<TImage> >
itk::CheckerBoardImageFilter<TImage>::New() [with TImage = ImageType]'
/usr/include/c++/3.2.2/iostream:12:   instantiated from here
/usr/include/c++/3.2.2/iostream:56: explicit instantiation of `
   itk::CheckerBoardImageFilter<TImage>::CheckerBoardImageFilter() [with TImage
   = ImageType]' but no definition
available/home/rbrooks/src/Insight/Code/BasicFilters/itkCheckerBoardImageFilter.h:
In instantiation of
`itk::CheckerBoardImageFilter<TImage>::CheckerBoardImageFilter() [with
TImage = ImageType]':/home/rbrooks/src/Insight/Code/BasicFilters/itkCheckerBoardImageFilter.h:56:
  instantiated from `static
itk::SmartPointer<itk::CheckerBoardImageFilter<TImage> >
itk::CheckerBoardImageFilter<TImage>::New() [with TImage =
ImageType]'/home/rbrooks/registration/src/tests/ExplicitInstantiationTest.cxx:12:
  instantiated from
here/home/rbrooks/src/Insight/Code/BasicFilters/itkCheckerBoardImageFilter.h:56:
explicit
   instantiation of `
   itk::CheckerBoardImageFilter<TImage>::CheckerBoardImageFilter() [with TImage
   = ImageType]' but no definition available



On 11/5/07, Brad King <brad.king at kitware.com> wrote:
> Rupert Brooks wrote:
> > I found this document
> > (http://www.itk.org/Wiki/Proposals:Explicit_Instantiation) but after
> > reading it i must confess i was still confused.  What i really wanted
> > to know was how, as a user, im supposed to manage this issue now.
> > After some difficulty, i got it to work by switching on
> > ITK_MANUAL_INSTANTIATION before including the relevant files.
> > Pseudocode follows.
>
> There is an option provided in the CMake interface called
> ITK_EXPLICIT_INSTANTIATION that causes a bunch of instantiations to be
> done for you this way.  You have to look in the 'advanced' options list
> to see it.  Turning it on provides many instantiations in the ITK
> libraries themselves.
>
> > Overall, it works, and i sped up my build by about a factor of 3,
> > which is what i wanted.  But i still have some problems, and i have a
> > gut feeling im doing it the "wrong way".  I wondered if people could
> > tell me what the "RIGHT" way to do this is.  Possibly some of these
> > problems are bugs, in which case i  should report them.  But im not
> > sure.
>
> You're approach is basically correct for doing this in an outside
> project.  ITK_MANUAL_INSTANTIATION was meant for exactly that.
>
> > 1. Not only did i have to explicitly instantiate all the classes that
> > i actually use, but i had to instantiate their parents in some cases.
> > Eventually, i just kept building, and whatever symbols the linker
> > couldnt find, i would manually instantiate.
>
> This is expected.
>
> > 2. After I have used ITK_MANUAL_INSTANTIATION to block the inclusion
> > of txx files i have to manually include them for templated classes i
> > do want to implicitly include.  Again, a minor annoyance, but makes me
> > wonder if im doing this wrong.
>
> This is expected.
>
> > 3. For at least one class, itkPoint.h, probably more, this approach
> > does not work because the helper functions to allow things like
> > std::cout << mypoint are not explicitly instantiated.  I made a few
> > unsuccessful attempts to explicitly instantiate them by using them in
> > dummy functions in my explicit.cxx file, but it didnt work.
>
> The non-members need to have their own explicit instantiation lines.  In
> the case of itkPoint.h the ITK_EXPLICIT_INSTANTIATION feature exports a
> few point type instantiations for you from ITKCommon.  Many types
> provide macros to help create all the necessary instantiations.  You can
> see them at the bottom of the header files (see itkPoint.h).  The macros
> in the headers are not meant to be called directly.  Their design is
> documented in that Wiki entry you mentioned.
>
> If you turn on ITK_EXPLICIT_INSTANTIATION you will find a bunch of
> directories like Code/Common/Templates in the build tree.  The files in
> these directory contain appropriate macro invocations.  They cause
> instantiations to be done explicitly inside libraries and then
> DLL-exported from them.  When a user includes the header they will see
> those instantations as DLL-imported (or at least marked as "extern"
> explicit instantiations to prevent implicit instantiation...a
> platform-specific extension available on most platforms).
>
> > 4. Certain classes dont seem to have all the members available for
> > instantiation.  On Visual C++ this gives a warning, on gcc 4, it is
> > ignored, and on gcc 3 it is a build-stopping error.  Whats very wierd
> > is i dont seem to be getting the same missing functions on gcc3 and
> > VC++.  Are these missing members a bug, or is there some trick to
> > instantiateing the classes?  I'm still investigating this one on gcc
> > 3.  Example warning message from VC++ follows.
>
> The missing methods are purposely not implemented.  They are the copy
> constructor and assignment operator of all classes in the
> itk::LightObject hierarchy.  See itkLightObject.h:
>
>   LightObject(const Self&); //purposely not implemented
>   void operator=(const Self&); //purposely not implemented
>
> There is code setup in itkMacro.h to block these warnings for Visual
> Studio inside the .cxx files created by the ITK_EXPLICIT_INSTANTIATION
> feature:
>
> #if ITK_TEMPLATE_CXX
> //...
> # if defined(_MSC_VER)
> #  pragma warning (disable: 4275) /* non dll-interface base */
> #  pragma warning (disable: 4661) /* no definition available */
> # endif
> #endif
>
> I have never seen warnings or errors from any version of GCC.
>
> -Brad
>


-- 
--------------------------------------------------------------
Rupert Brooks
McGill Centre for Intelligent Machines (www.cim.mcgill.ca)
Ph.D Student, Electrical and Computer Engineering
http://www.cyberus.ca/~rbrooks


More information about the Insight-users mailing list