Skip to content

Commit eb2316a

Browse files
committed
BUG: TransformIO: Implement explicit template instantiation using "extern".
This commit updates explicit instantiation to use "extern" keyword similarly to what was done in InsightSoftwareConsortium/ITK@b72726c (BUG: Explicitly instantiate common MetaDataObjects). By using the recommended approach for template instantiation, this commit should also fix TransformReadWriteTest where TransformIO failed to be successfully instantiated. Here is the error that was reported when the was compiled on MacOSX using clang-6.0: libc++abi.dylib: terminating with uncaught exception of type itk::ExceptionObject: /scratch/dashboards/MacOSX-clang6/ITK/Modules/IO/TransformBase/src/itkTransformFileWriterSpecializations.cxx:212: itk::ERROR: TransformFileWriterTemplate(0x7fa552100f10): The input of writer should be whether a double precision or a single precision transform type. Called from TransformFileWriterTemplate<double,double$ It also updates IOTransformDCMTK remote module to include a similar fix. Note #1: To shut up the following warning from gcc, context specific "pragma GCC diagnostic" preprocessor instructions have been added: warning: type attributes ignored after type is already defined [-Wattributes] This is most likely specific to gcc (see issue #39159), and at the time of this commit there were no resolution or information about gcc version where the "problem" is addressed. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=39159 For that reason, the "pragma GCC diagnostic" is applied in-conditionally of the gcc version being used. Note #2: While "extern" is only part of the c++ standard starting with c++11 (see section 14.7.2 of the standard), it is supported by Visual Studio 2008, GCC and Clang using compiler specific extension in earlier version: * Visual Studio 2008: https://msdn.microsoft.com/en-us/library/by56e477(v=vs.90).aspx * Gcc: https://gcc.gnu.org/onlinedocs/gcc-4.8.4/gcc/Template-Instantiation.html#Template-Instantiation * Clang (since v2.9): http://clang.llvm.org/cxx_status.html For completeness, initial draft of the "extern" keyword were first introduced in 2003 [1] and then revised in 2006 [2], and ultimately standardized in c++11 [3]: [1] N1448: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1448.pdf [2] N1987: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1987.htm [3] N3242: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/ See InsightSoftwareConsortium#3393 Suggested-by: Bradley Lowekamp <blowekamp@mail.nih.gov> Co-authored-by: Bradley Lowekamp <blowekamp@mail.nih.gov> Change-Id: I2e3ca2843c500b9bb60bbffc5f3629bc5be0a6fd
1 parent e6eaab0 commit eb2316a

34 files changed

+401
-87
lines changed

Modules/Core/SpatialObjects/itk-module.cmake

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ approximations of shape by combining them into hierarchical structures similar
66
to scene graphs.")
77

88
itk_module(ITKSpatialObjects
9+
DEPENDS
10+
ITKTransform
911
PRIVATE_DEPENDS
1012
ITKMesh
1113
ITKCommon

Modules/Core/Transform/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
project(ITKTransform)
2+
set(ITKTransform_LIBRARIES ITKTransform)
23
itk_module_impl()

Modules/Core/Transform/include/itkTransformBase.h

+18
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#ifndef itkTransformBase_h
1919
#define itkTransformBase_h
2020

21+
#include "ITKTransformExport.h"
22+
2123
#include "itkObject.h"
2224
#include "itkPoint.h"
2325
#include "itkCovariantVector.h"
@@ -147,6 +149,22 @@ class TransformBaseTemplate:public Object
147149
/** This helps to meet backward compatibility */
148150
typedef TransformBaseTemplate< double > TransformBase;
149151

152+
/** Explicit instantiations */
153+
#ifndef ITK_TEMPLATE_EXPLICIT_TransformBase
154+
// Explicit instantiation is required to ensure correct dynamic_cast
155+
// behavior across shared libraries.
156+
# if defined( ITKTransform_EXPORTS )
157+
// We are building this library
158+
# define ITKTransform_EXPORT_EXPLICIT
159+
# else
160+
// We are using this library
161+
# define ITKTransform_EXPORT_EXPLICIT ITKTransform_EXPORT
162+
# endif
163+
extern template class ITKTransform_EXPORT_EXPLICIT TransformBaseTemplate< double >;
164+
extern template class ITKTransform_EXPORT_EXPLICIT TransformBaseTemplate< float >;
165+
# undef ITKTransform_EXPORT_EXPLICIT
166+
#endif
167+
150168
} // end namespace itk
151169

152170
#endif

Modules/Core/Transform/itk-module.cmake

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ are a large family in ITK and form a prolific group of classes in the
77
toolkit.")
88

99
itk_module(ITKTransform
10+
ENABLE_SHARED
11+
DEPENDS
12+
ITKCommon
1013
COMPILE_DEPENDS
1114
ITKStatistics
1215
ITKImageFilterBase
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
set(ITKTransform_SRC
2+
itkTransformBase.cxx
3+
)
4+
5+
add_library(ITKTransform ${ITK_LIBRARY_BUILD_TYPE} ${ITKTransform_SRC})
6+
itk_module_link_dependencies()
7+
itk_module_target(ITKTransform)

Modules/IO/TransformHDF5/src/itkHDF5TransformIOInstantiation.cxx Modules/Core/Transform/src/itkTransformBase.cxx

+13-4
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,22 @@
1616
*
1717
*=========================================================================*/
1818

19-
#include "itkHDF5TransformIO.h"
20-
#include "itkHDF5TransformIO.hxx"
19+
#define ITK_TEMPLATE_EXPLICIT_TransformBase
20+
#include "itkTransformBase.h"
2121

2222
namespace itk
2323
{
2424

25-
template class HDF5TransformIOTemplate< double >;
26-
template class HDF5TransformIOTemplate< float >;
25+
#if defined( __GNUC__ )
26+
#pragma GCC diagnostic push
27+
#pragma GCC diagnostic ignored "-Wattributes"
28+
#endif
29+
30+
template class ITKTransform_EXPORT TransformBaseTemplate< double >;
31+
template class ITKTransform_EXPORT TransformBaseTemplate< float >;
32+
33+
#if defined( __GNUC__ )
34+
#pragma GCC diagnostic pop
35+
#endif
2736

2837
} // end namespace itk

Modules/IO/TransformBase/include/itkCompositeTransformIOHelper.h

+18-2
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ namespace itk
4545
* \ingroup ITKIOTransformBase
4646
*/
4747
template<typename TParametersValueType>
48-
class ITKIOTransformBase_EXPORT CompositeTransformIOHelperTemplate
48+
class CompositeTransformIOHelperTemplate
4949
{
5050
public:
5151
typedef typename TransformIOBaseTemplate<TParametersValueType>::TransformType TransformType;
@@ -93,8 +93,24 @@ class ITKIOTransformBase_EXPORT CompositeTransformIOHelperTemplate
9393
/** This helps to meet backward compatibility */
9494
typedef CompositeTransformIOHelperTemplate<double> CompositeTransformIOHelper;
9595

96+
/** Explicit instantiations */
97+
#ifndef ITK_TEMPLATE_EXPLICIT_CompositeTransformIOHelper
98+
// Explicit instantiation is required to ensure correct dynamic_cast
99+
// behavior across shared libraries.
100+
# if defined( ITKIOTransformBase_EXPORTS )
101+
// We are building this library
102+
# define ITKIOTransformBase_EXPORT_EXPLICIT
103+
# else
104+
// We are using this library
105+
# define ITKIOTransformBase_EXPORT_EXPLICIT ITKIOTransformBase_EXPORT
106+
# endif
107+
extern template class ITKIOTransformBase_EXPORT_EXPLICIT CompositeTransformIOHelperTemplate< double >;
108+
extern template class ITKIOTransformBase_EXPORT_EXPLICIT CompositeTransformIOHelperTemplate< float >;
109+
# undef ITKIOTransformBase_EXPORT_EXPLICIT
110+
#endif
111+
96112
} // namespace itk
97113

98-
// Note: Explicit instantiation is done in itkTransformFactoryBaseInstantiation.cxx
114+
// Note: Explicit instantiation is done in itkCompositeTransformIOHelper.cxx
99115

100116
#endif // itkCompositeTransformIOHelper_h

Modules/IO/TransformBase/include/itkTransformFileReader.h

+17-1
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,28 @@ class ITKIOTransformBase_EXPORT TransformFileReaderTemplate: public LightProcess
100100
/** This helps to meet backward compatibility */
101101
typedef itk::TransformFileReaderTemplate<double> TransformFileReader;
102102

103+
/** Explicit instantiations */
104+
#ifndef ITK_TEMPLATE_EXPLICIT_TransformFileReader
105+
// Explicit instantiation is required to ensure correct dynamic_cast
106+
// behavior across shared libraries.
107+
# if defined( ITKIOTransformBase_EXPORTS )
108+
// We are building this library
109+
# define ITKIOTransformBase_EXPORT_EXPLICIT
110+
# else
111+
// We are using this library
112+
# define ITKIOTransformBase_EXPORT_EXPLICIT ITKIOTransformBase_EXPORT
113+
# endif
114+
extern template class ITKIOTransformBase_EXPORT_EXPLICIT TransformFileReaderTemplate< double >;
115+
extern template class ITKIOTransformBase_EXPORT_EXPLICIT TransformFileReaderTemplate< float >;
116+
# undef ITKIOTransformBase_EXPORT_EXPLICIT
117+
#endif
118+
103119
} // namespace itk
104120

105121
#ifdef ITK_IO_FACTORY_REGISTER_MANAGER
106122
#include "itkTransformIOFactoryRegisterManager.h"
107123
#endif
108124

109-
// Note: Explicit instantiation is done in itkTransformFactoryBaseInstantiation.cxx
125+
// Note: Explicit instantiation is done in itkTransformFileReader.cxx
110126

111127
#endif // itkTransformFileReade_h

Modules/IO/TransformBase/include/itkTransformFileWriter.h

+32-1
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,43 @@ class ITKIOTransformBase_EXPORT TransformFileWriterTemplate:public LightProcessO
111111
/** This helps to meet backward compatibility */
112112
typedef itk::TransformFileWriterTemplate<double> TransformFileWriter;
113113

114+
#if defined( __GNUC__ )
115+
#pragma GCC diagnostic push
116+
#pragma GCC diagnostic ignored "-Wattributes"
117+
#endif
118+
119+
/** Declare specializations */
120+
template<> void ITKIOTransformBase_EXPORT TransformFileWriterTemplate< double >::PushBackTransformList(const Object *transObj);
121+
template<> void ITKIOTransformBase_EXPORT TransformFileWriterTemplate< float >::PushBackTransformList(const Object *transObj);
122+
123+
/** Explicit instantiations */
124+
#ifndef ITK_TEMPLATE_EXPLICIT_TransformFileWriter
125+
// Explicit instantiation is required to ensure correct dynamic_cast
126+
// behavior across shared libraries.
127+
# if defined( ITKIOTransformBase_EXPORTS )
128+
// We are building this library
129+
# define ITKIOTransformBase_EXPORT_EXPLICIT
130+
# else
131+
// We are using this library
132+
# define ITKIOTransformBase_EXPORT_EXPLICIT ITKIOTransformBase_EXPORT
133+
# endif
134+
135+
extern template class ITKIOTransformBase_EXPORT_EXPLICIT TransformFileWriterTemplate< double >;
136+
extern template class ITKIOTransformBase_EXPORT_EXPLICIT TransformFileWriterTemplate< float >;
137+
138+
# undef ITKIOTransformBase_EXPORT_EXPLICIT
139+
#endif
140+
141+
#if defined( __GNUC__ )
142+
#pragma GCC diagnostic push
143+
#endif
144+
114145
} // namespace itk
115146

116147
#ifdef ITK_IO_FACTORY_REGISTER_MANAGER
117148
#include "itkTransformIOFactoryRegisterManager.h"
118149
#endif
119150

120-
// Note: Explicit instantiation is done in itkTransformFactoryBaseInstantiation.cxx
151+
// Note: Explicit instantiation is done in itkTransformFileWriterSpecializations.cxx
121152

122153
#endif // itkTransformFileWriter_h

Modules/IO/TransformBase/include/itkTransformIOBase.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ namespace itk
4545
* \ingroup ITKIOTransformBase
4646
*/
4747
template<typename TParametersValueType>
48-
class ITKIOTransformBase_EXPORT TransformIOBaseTemplate:public LightProcessObject
48+
class TransformIOBaseTemplate:public LightProcessObject
4949
{
5050
public:
5151
/** Standard class typedefs */
@@ -185,6 +185,8 @@ typedef itk::TransformIOBaseTemplate<double> TransformIOBase;
185185

186186
} // end namespace itk
187187

188-
// Note: Explicit instantiation is done in itkTransformFactoryBaseInstantiation.cxx
188+
#ifndef ITK_MANUAL_INSTANTIATION
189+
#include "itkTransformIOBase.hxx"
190+
#endif
189191

190192
#endif // itkTransformIOBase_h

Modules/IO/TransformBase/include/itkTransformIOFactory.h

+17-2
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,24 @@ class ITKIOTransformBase_EXPORT TransformIOFactoryTemplate:public Object
6969
/** This helps to meet backward compatibility */
7070
typedef TransformIOFactoryTemplate<double> TransformIOFactory;
7171

72-
} // end namespace itk
72+
/** Explicit instantiations */
73+
#ifndef ITK_TEMPLATE_EXPLICIT_TransformIOFactory
74+
// Explicit instantiation is required to ensure correct dynamic_cast
75+
// behavior across shared libraries.
76+
# if defined( ITKIOTransformBase_EXPORTS )
77+
// We are building this library
78+
# define ITKIOTransformBase_EXPORT_EXPLICIT
79+
# else
80+
// We are using this library
81+
# define ITKIOTransformBase_EXPORT_EXPLICIT ITKIOTransformBase_EXPORT
82+
# endif
83+
extern template class ITKIOTransformBase_EXPORT_EXPLICIT TransformIOFactoryTemplate< double >;
84+
extern template class ITKIOTransformBase_EXPORT_EXPLICIT TransformIOFactoryTemplate< float >;
85+
# undef ITKIOTransformBase_EXPORT_EXPLICIT
86+
#endif
7387

88+
} // end namespace itk
7489

75-
// Note: Explicit instantiation is done in itkTransformFactoryBaseInstantiation.cxx
90+
// Note: Explicit instantiation is done in itkTransformIOFactory.cxx
7691

7792
#endif

Modules/IO/TransformBase/itk-module.cmake

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ itk_module(ITKIOTransformBase
55
ENABLE_SHARED
66
DEPENDS
77
ITKCommon
8-
PRIVATE_DEPENDS
98
ITKTransform
109
COMPILE_DEPENDS
1110
ITKDisplacementField

Modules/IO/TransformBase/src/CMakeLists.txt

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
set(ITKIOTransformBase_SRC
2+
itkCompositeTransformIOHelper.cxx
23
itkTransformFactoryBase.cxx
3-
itkTransformFactoryBaseInstantiation.cxx
4+
itkTransformFileReader.cxx
45
itkTransformFileWriterSpecializations.cxx
6+
itkTransformIOFactory.cxx
57
)
68

79
add_library(ITKIOTransformBase ${ITK_LIBRARY_BUILD_TYPE} ${ITKIOTransformBase_SRC})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*=========================================================================
2+
*
3+
* Copyright Insight Software Consortium
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0.txt
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*=========================================================================*/
18+
19+
#define ITK_TEMPLATE_EXPLICIT_CompositeTransformIOHelper
20+
#include "itkCompositeTransformIOHelper.h"
21+
#include "itkCompositeTransformIOHelper.hxx"
22+
23+
namespace itk
24+
{
25+
26+
#if defined( __GNUC__ )
27+
#pragma GCC diagnostic push
28+
#pragma GCC diagnostic ignored "-Wattributes"
29+
#endif
30+
31+
template class ITKIOTransformBase_EXPORT CompositeTransformIOHelperTemplate< double >;
32+
template class ITKIOTransformBase_EXPORT CompositeTransformIOHelperTemplate< float >;
33+
34+
#if defined( __GNUC__ )
35+
#pragma GCC diagnostic pop
36+
#endif
37+
38+
} // end namespace itk

Modules/IO/TransformBase/src/itkTransformFactoryBaseInstantiation.cxx

-52
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*=========================================================================
2+
*
3+
* Copyright Insight Software Consortium
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0.txt
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*=========================================================================*/
18+
19+
#define ITK_TEMPLATE_EXPLICIT_TransformFileReader
20+
#include "itkTransformFileReader.h"
21+
#include "itkTransformFileReader.hxx"
22+
23+
namespace itk
24+
{
25+
26+
#if defined( __GNUC__ )
27+
#pragma GCC diagnostic push
28+
#pragma GCC diagnostic ignored "-Wattributes"
29+
#endif
30+
31+
template class ITKIOTransformBase_EXPORT TransformFileReaderTemplate< double >;
32+
template class ITKIOTransformBase_EXPORT TransformFileReaderTemplate< float >;
33+
34+
#if defined( __GNUC__ )
35+
#pragma GCC diagnostic pop
36+
#endif
37+
38+
} // end namespace itk

0 commit comments

Comments
 (0)