min, max, GCC 2.95.3, and STLport

The new handling of min/max seems to break under GCC 2.95.3 with STLport. I'm not quite sure _why_ it doesn't work (I don't have the compiler around), but you can see the failure here: http://tinyurl.com/ytdlf Perhaps someone with that compiler/lib combination could get preprocessed output for the problem area so we could see what's happening? Doug

Doug Gregor wrote:
The new handling of min/max seems to break under GCC 2.95.3 with STLport. I'm not quite sure _why_ it doesn't work (I don't have the compiler around), but you can see the failure here:
Perhaps someone with that compiler/lib combination could get preprocessed output for the problem area so we could see what's happening?
Maybe this experiment sheds some light on the problem: I tried this code with gcc-2.95.3 and STLport: #include <boost/minmax.hpp> int foo() { BOOST_USING_STD_MIN(); return min BOOST_PREVENT_MACRO_SUBSTITUTION(3, 4); } namespace notboost { template <typename T> T const & proxy_min(T const &p, T const &q) { BOOST_USING_STD_MIN(); return min BOOST_PREVENT_MACRO_SUBSTITUTION(p, q); // line 16 } } int bar() { return notboost::proxy_min(3, 4); // line 22 } namespace test { int baz() { BOOST_USING_STD_MIN(); return min BOOST_PREVENT_MACRO_SUBSTITUTION(3, 4); } } int main() { foo(); bar(); test::baz(); } The compiler emits these error messages: min.cpp: In function `const int & notboost::proxy_min<int>(const int &, const int &)': min.cpp:22: instantiated from here min.cpp:16: `min' undeclared (first use this function) min.cpp:16: (Each undeclared identifier is reported only once min.cpp:16: for each function it appears in.) So it looks like gcc 2.95.3 doesn't handle the using declaration inside template functions properly. HTH, m

Martin Wille wrote:
Doug Gregor wrote:
The new handling of min/max seems to break under GCC 2.95.3 with STLport. I'm not quite sure _why_ it doesn't work (I don't have the compiler around), but you can see the failure here:
Perhaps someone with that compiler/lib combination could get preprocessed output for the problem area so we could see what's happening?
Maybe this experiment sheds some light on the problem: I tried this code with gcc-2.95.3 and STLport:
#include <boost/minmax.hpp>
int foo() { BOOST_USING_STD_MIN(); return min BOOST_PREVENT_MACRO_SUBSTITUTION(3, 4); }
namespace notboost { template <typename T> T const & proxy_min(T const &p, T const &q) { BOOST_USING_STD_MIN(); return min BOOST_PREVENT_MACRO_SUBSTITUTION(p, q); // line 16 } }
int bar() { return notboost::proxy_min(3, 4); // line 22 }
namespace test { int baz() { BOOST_USING_STD_MIN(); return min BOOST_PREVENT_MACRO_SUBSTITUTION(3, 4); } }
int main() { foo(); bar(); test::baz(); }
The compiler emits these error messages: min.cpp: In function `const int & notboost::proxy_min<int>(const int &, const int &)': min.cpp:22: instantiated from here min.cpp:16: `min' undeclared (first use this function) min.cpp:16: (Each undeclared identifier is reported only once min.cpp:16: for each function it appears in.)
So it looks like gcc 2.95.3 doesn't handle the using declaration inside template functions properly.
HTH, m
Ugh. Thanks Martyn. Can you tell me if there is something funny about the way STLPort defines std::min/max? Does it use macros? Or are they defined globally and imported into the std:: namespace with using declarations? In the worst case, I suppose for this compiler/library combination we can import std::min/max into the boost namespace with a using declaration and make BOOST_USING_STD_MIN() expand to nothing. Martyn, can you try that and see if it works? -- Eric Niebler Boost Consulting www.boost-consulting.com

Eric Niebler wrote:
Martin Wille wrote: ...
#include <boost/minmax.hpp>
int foo() { BOOST_USING_STD_MIN(); return min BOOST_PREVENT_MACRO_SUBSTITUTION(3, 4); }
namespace notboost { template <typename T> T const & proxy_min(T const &p, T const &q) { BOOST_USING_STD_MIN(); return min BOOST_PREVENT_MACRO_SUBSTITUTION(p, q); // line 16 } }
int bar() { return notboost::proxy_min(3, 4); // line 22 }
namespace test { int baz() { BOOST_USING_STD_MIN(); return min BOOST_PREVENT_MACRO_SUBSTITUTION(3, 4); } }
int main() { foo(); bar(); test::baz(); }
The compiler emits these error messages: min.cpp: In function `const int & notboost::proxy_min<int>(const int &, const int &)': min.cpp:22: instantiated from here min.cpp:16: `min' undeclared (first use this function) min.cpp:16: (Each undeclared identifier is reported only once min.cpp:16: for each function it appears in.)
Ugh. Thanks Martyn. Can you tell me if there is something funny about the way STLPort defines std::min/max? Does it use macros? Or are they defined globally and imported into the std:: namespace with using declarations?
STLPort implements std::min in the namespace _STL. BOOST_USING_STD_MIN() correctly expands to: using _STL ::min The (shortened) result of preprocessing is: namespace _STL { template <class _Tp> inline const _Tp& (min)(const _Tp& __a, const _Tp& __b) { return __b < __a ? __b : __a; } template <class _Tp> inline const _Tp& (max)(const _Tp& __a, const _Tp& __b) { return __a < __b ? __b : __a; } template <class _Tp, class _Compare> inline const _Tp& (min)(const _Tp& __a, const _Tp& __b, _Compare __comp) { return __comp(__b, __a) ? __b : __a; } template <class _Tp, class _Compare> inline const _Tp& (max)(const _Tp& __a, const _Tp& __b, _Compare __comp) { return __comp(__a, __b) ? __b : __a; } } (the complete preprocessed source can be found at: http://tinyurl.com/yrflf ) I must be blind, I can't spot the line that hoists the contents of _STL:: into std::.
In the worst case, I suppose for this compiler/library combination we can import std::min/max into the boost namespace with a using declaration and make BOOST_USING_STD_MIN() expand to nothing. Martyn, can you try that and see if it works?
Changing the source to namespace notboost { BOOST_USING_STD_MIN(); // moved to namespace scope template <typename T> T const & proxy_min(T const &p, T const &q) { return min BOOST_PREVENT_MACRO_SUBSTITUTION(p, q); } } indeed makes gcc-2.95.3 accept the code. Regards, m

Martin Wille wrote:
STLPort implements std::min in the namespace _STL. BOOST_USING_STD_MIN() correctly expands to: using _STL ::min
The (shortened) result of preprocessing is:
namespace _STL {
template <class _Tp> inline const _Tp& (min)(const _Tp& __a, const _Tp& __b) { return __b < __a ? __b : __a; } template <class _Tp> inline const _Tp& (max)(const _Tp& __a, const _Tp& __b) { return __a < __b ? __b : __a; }
template <class _Tp, class _Compare> inline const _Tp& (min)(const _Tp& __a, const _Tp& __b, _Compare __comp) { return __comp(__b, __a) ? __b : __a; }
template <class _Tp, class _Compare> inline const _Tp& (max)(const _Tp& __a, const _Tp& __b, _Compare __comp) { return __comp(__a, __b) ? __b : __a; }
}
(the complete preprocessed source can be found at: http://tinyurl.com/yrflf )
I must be blind, I can't spot the line that hoists the contents of _STL:: into std::.
It's not there. STLPort must be #defining std to _STL.
In the worst case, I suppose for this compiler/library combination we can import std::min/max into the boost namespace with a using declaration and make BOOST_USING_STD_MIN() expand to nothing. Martyn, can you try that and see if it works?
Changing the source to
namespace notboost { BOOST_USING_STD_MIN(); // moved to namespace scope template <typename T> T const & proxy_min(T const &p, T const &q) { return min BOOST_PREVENT_MACRO_SUBSTITUTION(p, q); } }
indeed makes gcc-2.95.3 accept the code.
Well then, I guess that's what I'll do, unless somebody has a better idea. I'll sleep on it first. Thanks again, Martin. -- Eric Niebler Boost Consulting www.boost-consulting.com

"Eric Niebler" <eric@boost-consulting.com> writes:
Martin Wille wrote:
STLPort implements std::min in the namespace _STL. BOOST_USING_STD_MIN() correctly expands to: using _STL ::min The (shortened) result of preprocessing is: namespace _STL { template <class _Tp> inline const _Tp& (min)(const _Tp& __a, const _Tp& __b) { return __b < __a ? __b : __a; } template <class _Tp> inline const _Tp& (max)(const _Tp& __a, const _Tp& __b) { return __a < __b ? __b : __a; } template <class _Tp, class _Compare> inline const _Tp& (min)(const _Tp& __a, const _Tp& __b, _Compare __comp) { return __comp(__b, __a) ? __b : __a; } template <class _Tp, class _Compare> inline const _Tp& (max)(const _Tp& __a, const _Tp& __b, _Compare __comp) { return __comp(__a, __b) ? __b : __a; } } (the complete preprocessed source can be found at: http://tinyurl.com/yrflf ) I must be blind, I can't spot the line that hoists the contents of _STL:: into std::.
It's not there. STLPort must be #defining std to _STL.
Yes, that's what it does. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com
participants (4)
-
David Abrahams
-
Doug Gregor
-
Eric Niebler
-
Martin Wille