Problem with dll and BOOST_STATIC_ASSERT
I have the following code ( very simplified but compilable)
// =========== start snip ===============================
/// ======= in hpp ============
#include
Frank wrote:
I 'm trying to put the implementation into a dll and mark the explicit instantiation of Normal as exported with the following results: 1) With the small_dim_ctor's enabled I get the static assertion when marked for export 2) With the small_dim_ctor's enabled everything is ok when not marked for export 3) With the small_dim_ctor's disabled everything is ok regardless of export marking 4) If I comment out the BOOST_STATIC_ASSERT and build my app with export enabled I can use the resulting dll without any problems
I'm thinking that marking for export is somewhow generating an implicit conversion somewhere but I don't know how.
I suppose marking the class for export could instantiate all member functions and constructors and thus trigger the static assertions. Have you considered using boost::enable_if instead of BOOST_STATIC_ASSERT? Regards, João Abecasis
João Abecasis
Frank wrote:
I 'm trying to put the implementation into a dll and mark the explicit instantiation of Normal as exported with the following results: 1) With the small_dim_ctor's enabled I get the static assertion when marked for export 2) With the small_dim_ctor's enabled everything is ok when not marked for export 3) With the small_dim_ctor's disabled everything is ok regardless of export marking 4) If I comment out the BOOST_STATIC_ASSERT and build my app with export enabled I can use the resulting dll without any problems
I'm thinking that marking for export is somewhow generating an implicit conversion somewhere but I don't know how.
I suppose marking the class for export could instantiate all member functions and constructors and thus trigger the static assertions.
Have you considered using boost::enable_if instead of BOOST_STATIC_ASSERT?
Regards,
João Abecasis
I thought I was only marking the explicit specialization of a single method ( eg Normal) for exporting or maybe it's because its not possible to specialize just one method.? After reading your reply I had a look at enable_if but I couldn't figure a way to test the DIM ie template <typename T> explicit Vector( T x, typename boost::enable_if< DIM==1, void*>::type = 0 ) { data_[0]=x; } but I'm not sure I understand how to use it and am still surfing for examples. Thanks for the help. Frank
I 'm trying to put the implementation into a dll and mark the explicit instantiation of Normal as exported with the following results: 1) With the small_dim_ctor's enabled I get the static assertion when marked for export 2) With the small_dim_ctor's enabled everything is ok when not marked for export 3) With the small_dim_ctor's disabled everything is ok regardless of export marking 4) If I comment out the BOOST_STATIC_ASSERT and build my app with export enabled I can use the resulting dll without any problems
I'm thinking that marking for export is somewhow generating an implicit conversion somewhere but I don't know how.
Unfortunately, when you explicitly instantiate a template every non-template member function gets instantiated, and that triggers the static asserts. The only workarounds I can see are: 1) Use regular asserts whenever the class is being exported rather than static asserts. 2) Use partial template specialisations for the N = 1, 2 or 3 cases and give them different constructors (no need to static asserts then). 3) Use template constructors instead: template <class U> explicit Vector( U x ) { BOOST_STATIC_ASSERT(DIM==1); data_[0]=x; } Hope this helps, John.
John Maddock
I 'm trying to put the implementation into a dll and mark the explicit instantiation of Normal as exported with the following results: 1) With the small_dim_ctor's enabled I get the static assertion when marked for export 2) With the small_dim_ctor's enabled everything is ok when not marked for export 3) With the small_dim_ctor's disabled everything is ok regardless of export marking 4) If I comment out the BOOST_STATIC_ASSERT and build my app with export enabled I can use the resulting dll without any problems
I'm thinking that marking for export is somewhow generating an implicit conversion somewhere but I don't know how.
Unfortunately, when you explicitly instantiate a template every non-template member function gets instantiated, and that triggers the static asserts.
The only workarounds I can see are:
1) Use regular asserts whenever the class is being exported rather than static asserts. 2) Use partial template specialisations for the N = 1, 2 or 3 cases and give them different constructors (no need to static asserts then). 3) Use template constructors instead:
template <class U> explicit Vector( U x ) { BOOST_STATIC_ASSERT(DIM==1); data_[0]=x; }
Hope this helps, John.
I thought I was only marking the explicit specialization of a single method ( eg Normal) for exporting or maybe it's because its not possible to specialize just one method.? After reading your reply I had a look at enable_if but I couldn't figure a way to test the DIM ie template <typename T> explicit Vector( T x, typename boost::enable_if< DIM==1, void*>::type = 0 ) { data_[0]=x; } but I'm not sure I understand how to use it and am still surfing for examples. Thanks for the help. Frank
Sorry. Posted to wrong reply. Frank
John Maddock
I 'm trying to put the implementation into a dll and mark the explicit instantiation of Normal as exported with the following results: 1) With the small_dim_ctor's enabled I get the static assertion when marked for export 2) With the small_dim_ctor's enabled everything is ok when not marked for export 3) With the small_dim_ctor's disabled everything is ok regardless of export marking 4) If I comment out the BOOST_STATIC_ASSERT and build my app with export enabled I can use the resulting dll without any problems
I'm thinking that marking for export is somewhow generating an implicit conversion somewhere but I don't know how.
Unfortunately, when you explicitly instantiate a template every non-template member function gets instantiated, and that triggers the static asserts.
The only workarounds I can see are:
1) Use regular asserts whenever the class is being exported rather than static asserts. 2) Use partial template specialisations for the N = 1, 2 or 3 cases and give them different constructors (no need to static asserts then). 3) Use template constructors instead:
template <class U> explicit Vector( U x ) { BOOST_STATIC_ASSERT(DIM==1); data_[0]=x; }
Hope this helps, John.
Soln 1) I was trying for compile time checks but will fall back to this
Soln 2) I understood partial specialization wasn't supported in VStudio but I
might do this for float, double and dim 1-4; I had started to do something
similar by deriving Vector3<T> template from Vector
Soln 1) I was trying for compile time checks but will fall back to this
Understood. It's a weird error: I don't believe that the compiler should be instantiating those methods at all, but <shrug>.
Soln 2) I understood partial specialization wasn't supported in VStudio but I might do this for float, double and dim 1-4; I had started to do something similar by deriving Vector3<T> template from Vector
when I ran into the trouble.
Partial specialisation works just fine in Visual Studio 2003 (VC7.1 and later).
Soln 3) I like this one but haven't made it work yet. It succeeds if I export the specialized Vector
::Normal() but not if I export Vector3<T>::Normal () but i'm working on it ;-)
Your right, I've just tried it out, and it leads to even stranger errors: the template members get instantiated with some really strange argument types, I've no idea what's going on there at present. John.
John Maddock
It's a weird error: I don't believe that the compiler should be instantiating those methods at all, but <shrug>.
I don't have access to any other compilers so don't know if it's a VStudio problem.
Partial specialisation works just fine in Visual Studio 2003 (VC7.1 and later).
I could never get it to work but it may be my lack of understanding even tho I looked at dozens of examples.
Soln 3) I like this one but haven't made it work yet. It succeeds if I export the specialized Vector
::Normal() but not if I export Vector3<T>::Normal () but i'm working on it Your right, I've just tried it out, and it leads to even stranger errors: the template members get instantiated with some really strange argument types, I've no idea what's going on there at present.
I converted my template hierarchy to get rid of the Vector3<T> derivation
and added the "low Dim" ctor's to the Vector
participants (3)
-
Frank
-
John Maddock
-
João Abecasis