
Borland doesn't like boost::addressof when used with arrays. It won't let you reinterpret_cast from an array reference to a char &. Russell Hind was good enough to test the following patch for me and confirmed that it works around the problem. (This is needed to get BOOST_FOREACH to work with Borland.) If no one objects, I'll apply the patch myself. -- Eric Niebler Boost Consulting www.boost-consulting.com Index: addressof.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/utility/addressof.hpp,v retrieving revision 1.7 diff -b -d -u -r1.7 addressof.hpp --- addressof.hpp 27 Jul 2004 03:43:33 -0000 1.7 +++ addressof.hpp 14 Mar 2005 18:15:31 -0000 @@ -33,6 +33,22 @@ &const_cast<char&>(reinterpret_cast<const volatile char &>(v))); } +// Borland doesn't like casting an array reference to a char reference +// but thes overloads work around the problem. +# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +template<typename T,std::size_t N> +T (*addressof(T (&t)[N]))[N] +{ + return reinterpret_cast<T(*)[N]>(&t); +} + +template<typename T,std::size_t N> +const T (*addressof(const T (&t)[N]))[N] +{ + return reinterpret_cast<const T(*)[N]>(&t); +} +# endif + } #endif // BOOST_UTILITY_ADDRESSOF_HPP

Eric Niebler wrote:
+// Borland doesn't like casting an array reference to a char reference +// but thes overloads work around the problem. +# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +template<typename T,std::size_t N> +T (*addressof(T (&t)[N]))[N] +{ + return reinterpret_cast<T(*)[N]>(&t); +}
Why are you reinterpret_casting &t to itself? Is this a Borland problem as well?

Peter Dimov wrote:
Eric Niebler wrote:
+// Borland doesn't like casting an array reference to a char reference +// but thes overloads work around the problem. +# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +template<typename T,std::size_t N> +T (*addressof(T (&t)[N]))[N] +{ + return reinterpret_cast<T(*)[N]>(&t); +}
Why are you reinterpret_casting &t to itself? Is this a Borland problem as well?
Russell added the reinterpret_casts to my patch. Russell, can you comment? -- Eric Niebler Boost Consulting www.boost-consulting.com

Eric Niebler wrote:
Peter Dimov wrote:
Eric Niebler wrote:
+// Borland doesn't like casting an array reference to a char reference +// but thes overloads work around the problem. +# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +template<typename T,std::size_t N> +T (*addressof(T (&t)[N]))[N] +{ + return reinterpret_cast<T(*)[N]>(&t); +}
Why are you reinterpret_casting &t to itself? Is this a Borland problem as well?
Russell added the reinterpret_casts to my patch. Russell, can you comment?
And here is Russell's reply. Looks like it's necessary.
Truth is, I'm not sure why I reinterpret_cast t to its own type, but without it (i.e just return &t as Eric's original solution), FOREACH still gives these errors
[C++] main.cpp(1): [C++ Error] addressof.hpp(42): E2034 Cannot convert 'int *' to 'int ( *)[5]' [C++ Error] addressof.hpp(49): E2034 Cannot convert 'const int *' to 'int ( *) const[5]' As far as I can tell, the reinterpret_cast I've added isn't casting t to itself, as t is a T(&)[N], I'm reinterpret_casting it to the function return type, T(*)[N]. If this is incorrect, I can try other solutions if anyone has any suggestions, but just return &t doesn't work with bcc32-5.6.4. <<< -- Eric Niebler Boost Consulting www.boost-consulting.com

"Eric Niebler" <eric@boost-consulting.com> writes:
Eric Niebler wrote:
Peter Dimov wrote:
Eric Niebler wrote:
+// Borland doesn't like casting an array reference to a char reference +// but thes overloads work around the problem. +# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +template<typename T,std::size_t N> +T (*addressof(T (&t)[N]))[N] +{ + return reinterpret_cast<T(*)[N]>(&t); +}
Why are you reinterpret_casting &t to itself? Is this a Borland problem as well? Russell added the reinterpret_casts to my patch. Russell, can you comment?
And here is Russell's reply. Looks like it's necessary.
Truth is, I'm not sure why I reinterpret_cast t to its own type, but without it (i.e just return &t as Eric's original solution), FOREACH still gives these errors
[C++] main.cpp(1): [C++ Error] addressof.hpp(42): E2034 Cannot convert 'int *' to 'int ( *)[5]' [C++ Error] addressof.hpp(49): E2034 Cannot convert 'const int *' to 'int ( *) const[5]'
As far as I can tell, the reinterpret_cast I've added isn't casting t to itself, as t is a T(&)[N], I'm reinterpret_casting it to the function return type, T(*)[N].
If this is incorrect, I can try other solutions if anyone has any suggestions, but just return &t doesn't work with bcc32-5.6.4. <<<
You might see if static_cast works there. -- Dave Abrahams Boost Consulting www.boost-consulting.com

Eric Niebler wrote:
Peter Dimov wrote:
Eric Niebler wrote:
+// Borland doesn't like casting an array reference to a char reference +// but thes overloads work around the problem. +# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +template<typename T,std::size_t N> +T (*addressof(T (&t)[N]))[N] +{ + return reinterpret_cast<T(*)[N]>(&t); +}
Why are you reinterpret_casting &t to itself? Is this a Borland problem as well?
Russell added the reinterpret_casts to my patch. Russell, can you comment?
It's not that important, I was just curious. What's more important is that we don't seem to have a test case for the functionality. addressof_test is pretty basic.

Peter Dimov wrote:
It's not that important, I was just curious. What's more important is that we don't seem to have a test case for the functionality. addressof_test is pretty basic.
Yes, that's an oversight on my part. I've attached a patch to addressof_test.cpp to test for taking the address of an array. I can confirm that these new tests pass with VC7.1 and gcc 3.3.3 (cygwin). -- Eric Niebler Boost Consulting www.boost-consulting.com Index: addressof_test.cpp =================================================================== RCS file: /cvsroot/boost/boost/libs/utility/addressof_test.cpp,v retrieving revision 1.4 diff -b -d -u -r1.4 addressof_test.cpp --- addressof_test.cpp 3 Feb 2005 13:41:16 -0000 1.4 +++ addressof_test.cpp 14 Mar 2005 21:20:38 -0000 @@ -37,5 +37,13 @@ const volatile nonaddressable& cvx = *px; BOOST_CHECK(boost::addressof(cvx) == static_cast<const volatile nonaddressable*>(px)); + int nrg[3] = {1,2,3}; + int (*pnrg)[3] = &nrg; + BOOST_CHECK(boost::addressof(nrg) == pnrg); + + int const cnrg[3] = {1,2,3}; + int const (*pcnrg)[3] = &cnrg; + BOOST_CHECK(boost::addressof(cnrg) == pcnrg); + return 0; }

Eric Niebler wrote:
Peter Dimov wrote:
It's not that important, I was just curious. What's more important is that we don't seem to have a test case for the functionality. addressof_test is pretty basic.
Yes, that's an oversight on my part. I've attached a patch to addressof_test.cpp to test for taking the address of an array. I can confirm that these new tests pass with VC7.1 and gcc 3.3.3 (cygwin).
Great! Please go ahead and commit if you haven't already.
participants (4)
-
David Abrahams
-
Eric Niebler
-
Peter Dimov
-
Russell Hind