c++ - [Bug report] Bugs affecting boost::is_convertible
- Daniel James (47/47) Aug 15 2004 Hi,
- Walter (5/23) Aug 15 2004 I've had a lot of trouble with const, as sometimes it means a different ...
- Daniel James (10/13) Aug 16 2004 Well, I'm not 100% sure, I'm not a languague lawyer. The fact that the
- Daniel James (33/33) Aug 16 2004 It looks like there's the same problem with const void. Personally, I'm
Hi, I've been trying to get boost::is_convertible to work, and my version almost always does. But there are a few problems. The first one is a bit odd. In the following test case, if the commented out line is uncommented the program fails on the second function call. I believe that the compiler is reusing the instantiated template test<int[2]> when it instantiates test<const int[2]> which gives test<const int[2]>::func a non-const argument type. This causes a lot of the unit tests for the boost type_traits to fail. template<class T> struct test { static void func(T x) {} }; int main() { int x[2] = {1, 2}; //test<int[2]>::func(x); const int x2[2] = {1, 2}; test<const int[2]>::func(x2); } Secondly, void* shouldn't be implicitly convertible to other pointer types, and non-const references shouldn't be initialised from temporaries (the compiler warns about that, but it should be an error). Here are the test cases: int main() { int x; char& x2 = x; // This should fail, there is currently a warning } and: int main() { void* y; int* y2 = y; // This should fail } Finally, in the following example the compiler gives a link error because it can't find test::from, but as from is only referred to from the 'sizeof' it shouldn't be linked to. (In boost::is_convertible this is actually in a template, such that 'from' won't have a default constructor, which is why an instance of it can't be defined). I've actually got a work around for this one, but it's a little nasty, so it would be nice if this was fixed. struct test { static char from; }; int check(int const&); const int value = sizeof(check(test::from)); int main(){ } thanks, Daniel
Aug 15 2004
"Daniel James" <daniel calamity.org.uk> wrote in message news:411FC75F.9050804 calamity.org.uk...The first one is a bit odd. In the following test case, if the commented out line is uncommented the program fails on the second function call. I believe that the compiler is reusing the instantiated template test<int[2]> when it instantiates test<const int[2]> which gives test<const int[2]>::func a non-const argument type. This causes a lot of the unit tests for the boost type_traits to fail. template<class T> struct test { static void func(T x) {} }; int main() { int x[2] = {1, 2}; //test<int[2]>::func(x); const int x2[2] = {1, 2}; test<const int[2]>::func(x2); }I've had a lot of trouble with const, as sometimes it means a different type and sometimes it doesn't. Are you sure it really means a different template should be instantiated here?
Aug 15 2004
Walter wrote:I've had a lot of trouble with const, as sometimes it means a different type and sometimes it doesn't. Are you sure it really means a different template should be instantiated here?Well, I'm not 100% sure, I'm not a languague lawyer. The fact that the first instantiation breaks the second seems to suggest that it should, and the other compilers I've tried have no problems with this. Having said that, it's not a big problem. As far as type_traits are concerned, it may cause some of the tests to fail, but it's unlikely to cause a problem in normal use. I'm sure you've got a lot of far more important things to worry about. thanks, Daniel
Aug 16 2004
It looks like there's the same problem with const void. Personally, I'm surprised that you can have a const void. Here's a simple test: template <class T> struct add_pointer { typedef T* type; }; int main() { void* x; add_pointer<void>::type x1 = x; const void* y; add_pointer<const void>::type y1 = y; } Here's a longer, but more realistic, test: template <typename T> struct is_const_impl {}; template <typename T> struct is_const_impl<T*> { static const bool value = false; }; template <typename T> struct is_const_impl<const T*> { static const bool value = true; }; template <typename T> struct is_const { static const bool value = is_const_impl<T*>::value; }; #define STATIC_ASSERT(name, x) \ typedef char name[(x) ? 1 : -1]; STATIC_ASSERT(test_const_void, is_const<const void>::value); STATIC_ASSERT(test_void, !is_const<void>::value); STATIC_ASSERT(test_const_array, is_const<const int[2]>::value); STATIC_ASSERT(test_array, !is_const<int[2]>::value); Volatile acts in a similar manner. But, as I said before, this is unlikely to cause problems in normal use. Daniel
Aug 16 2004