Re: [boost] [test] test/included min max macro issue

----Original Message---- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Paul A Bristow Sent: 24 June 2006 14:34 To: boost@lists.boost.org Subject: Re: [boost] [test] test/included min max macro issue
A further quick question on this problem.
It is my custom (having a strong view that it aids readers - including me - of my programs) to write
#include <limits> using std::numeric_limits;
How do I avoid min/max macro problems when writing, for example,
return numeric_limits<double>::max(); ?
(numeric_limits<double>)::max(); ??? No.
From the website:
# If you want to call std::numeric_limits<int>::max(), use (std::numeric_limits<int>::max)() instead.>
The basic rule is that you must never have the (pp-)tokens "max" and "(" one after the other. If you do, the preprocessor will try to expand the max macro. The solution is to wrap the function name in parens, so what you would write is: return (numeric_limits<double::max)(); That means the preprocessore sees "max" and ")", and doesn't try to expand the macro. -- Martin Bonner Martin.Bonner@Pitechnology.com Pi Technology, Milton Hall, Ely Road, Milton, Cambridge, CB4 6WZ, ENGLAND Tel: +44 (0)1223 203894

| -----Original Message----- | From: boost-bounces@lists.boost.org | [mailto:boost-bounces@lists.boost.org] On Behalf Of Martin Bonner | Sent: 26 June 2006 11:59 | To: boost@lists.boost.org | Subject: Re: [boost] [test] test/included min max macro issue | | ----Original Message---- | From: boost-bounces@lists.boost.org | [mailto:boost-bounces@lists.boost.org] On Behalf Of Paul A Bristow | Sent: 24 June 2006 14:34 To: boost@lists.boost.org | Subject: Re: [boost] [test] test/included min max macro issue | | > A further quick question on this problem. | > | > It is my custom (having a strong view that it aids readers - | > including me - | > of my programs) to write | > | > #include <limits> | > using std::numeric_limits; | > | > How do I avoid min/max macro problems when writing, for example, | > | > return numeric_limits<double>::max(); ? | >From the website: | >> > # If you want to call std::numeric_limits<int>::max(), use | >> > (std::numeric_limits<int>::max)() instead.> | | The basic rule is that you must never have the (pp-)tokens | "max" and "(" | one after the other. If you do, the preprocessor will try | to expand the max macro. | | The solution is to wrap the function name in parens, so what | you would write is: | | return (numeric_limits<double::max)(); | | That means the preprocessor sees "max" and ")", and doesn't try to | expand the macro. Thanks, I am now better disambiguated - if at present macro vulnerable ;-( Perhaps Tonto can add this to the Boost Guidelines ;-) Paul --- Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB +44 1539561830 & SMS, Mobile +44 7714 330204 & SMS pbristow@hetp.u-net.com

On Mon, 26 Jun 2006 11:58:30 +0100, "Martin Bonner" <martin.bonner@pitechnology.com> wrote:
The basic rule is that you must never have the (pp-)tokens "max" and "(" one after the other.
Yes.
If you do, the preprocessor will try to expand the max macro.
The solution is to wrap the function name in parens
It's not the only solution, fortunately (the parentheses in general also prevent ADL). You can use anything different than an open paren which doesn't change the meaning of the construct after the preprocessing phase. For instance: #define DONT_EXPAND_ANY_HOMONYMOUS_MACRO return [std::]numeric_limits<double>::max DONT_EXPAND_ANY_HOMONYMOUS_MACRO (); Of course that's exactly what BOOST_PREVENT_MACRO_SUBSTITUTION is for. FWIW, I would prefer for it to be named something like BOOST_GUARD_FROM_FUNCTION_LIKE_MACRO, as it does not apply to object-like macros. --Gennaro.

"Gennaro Prota" wrote
On Mon, 26 Jun 2006 11:58:30 +0100, "Martin Bonner" <martin.bonner@pitechnology.com> wrote:
The basic rule is that you must never have the (pp-)tokens "max" and "(" one after the other.
Yes.
If you do, the preprocessor will try to expand the max macro.
The solution is to wrap the function name in parens
It's not the only solution, fortunately (the parentheses in general also prevent ADL). You can use anything different than an open paren which doesn't change the meaning of the construct after the preprocessing phase. For instance:
#define DONT_EXPAND_ANY_HOMONYMOUS_MACRO
return [std::]numeric_limits<double>::max DONT_EXPAND_ANY_HOMONYMOUS_MACRO ();
Of course that's exactly what BOOST_PREVENT_MACRO_SUBSTITUTION is for. FWIW, I would prefer for it to be named something like BOOST_GUARD_FROM_FUNCTION_LIKE_MACRO, as it does not apply to object-like macros.
Ahh that works! : #include <windows.h> #include <boost/config.hpp> struct my{ typedef int min; }; int main() { int n = my::min BOOST_PREVENT_MACRO_SUBSTITUTION (); } :-) regards Andy Little

"Martin Bonner" wrote
The solution is to wrap the function name in parens, so what you would write is:
return (numeric_limits<double::max)();
That means the preprocessore sees "max" and ")", and doesn't try to expand the macro.
Doesnt work for this scenario though: #include <windows.h> struct my{ typedef int min; }; int main() { int n = my::min(); } regards Andy Little
participants (4)
-
Andy Little
-
Gennaro Prota
-
Martin Bonner
-
Paul A Bristow