Some trouble with qldefines.hpp

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Some trouble with qldefines.hpp

Nicolas Di Césaré
Hi all,

I have some trouble with numeric_limits<>::max() under visual C++. It conflicts
with macro max. I am not able to provide a simple example where it occurs but
it seems to work with the following changes (the whole file is in attachement):

#if defined HAVE_LIMITS
    #include <limits>
    #define QL_MIN_INT      (int)(std::numeric_limits<int>::min)()
    #define QL_MAX_INT      (int)(std::numeric_limits<int>::max)()
    #define QL_MIN_DOUBLE  -(double)(std::numeric_limits<double>::max)()
    #define QL_MAX_DOUBLE   (double)(std::numeric_limits<double>::max)()
    #define QL_EPSILON      (double)(std::numeric_limits<double>::epsilon)()
    #define QL_MIN_POSITIVE_DOUBLE  (double)(std::numeric_limits<double>::min)()
...


I have also done the test with Intel C++ (visual studio pluggin) and I don't
have any  trouble.

Thus, I believe that it's visual C++ problem ...





--
Nicolas Di Césaré
http://acm.emath.fr/~dicesare

qldefines.hpp (13K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Some trouble with qldefines.hpp

Luigi Ballabio-4
At 11:39 AM 10/31/01 +0100, Nicolas Di Césaré wrote:
>Hi all,
>
>I have some trouble with numeric_limits<>::max() under visual C++. It
>conflicts with macro max.

Oh, yes, of course. Visual C++ does not supply std::max, but defines a max
macro instead. Absolute genius. Not.

>I am not able to provide a simple example where it occurs but
>it seems to work with the following changes (the whole file is in
>attachement):
>
>#if defined HAVE_LIMITS
>     #include <limits>
>     #define QL_MIN_INT      (int)(std::numeric_limits<int>::min)()
>     #define QL_MAX_INT      (int)(std::numeric_limits<int>::max)()
>     #define QL_MIN_DOUBLE  -(double)(std::numeric_limits<double>::max)()
>     #define QL_MAX_DOUBLE   (double)(std::numeric_limits<double>::max)()
>     #define QL_EPSILON      (double)(std::numeric_limits<double>::epsilon)()
>     #define
> QL_MIN_POSITIVE_DOUBLE  (double)(std::numeric_limits<double>::min)()
>...

I have used your file with Borland C++ as well without any problem, and I
checked the modifications into CVS.

I'm curious, though: why are the (int) and (double) casts required? Maybe
in order to shield the function pointer from precedence problems between ()
and some operator before the macro? Would
#define QL_MIN_INT      ((std::numeric_limits<int>::min)())
#define QL_MAX_INT     ((std::numeric_limits<int>::max)())
#define QL_MIN_DOUBLE  -((std::numeric_limits<double>::max)())
...
work for you instead?

Bye,
         Luigi



Reply | Threaded
Open this post in threaded view
|

Re: Some trouble with qldefines.hpp

Nicolas Di Césaré
En réponse à Luigi Ballabio <[hidden email]>:

> I'm curious, though: why are the (int) and (double) casts required?

Because it's not required ;-)
I have tried many things and probably one error message in visual let me assume
that it was required.


--
Nicolas Di Césaré
http://acm.emath.fr/~dicesare


Reply | Threaded
Open this post in threaded view
|

RE: Some trouble with qldefines.hpp

Jens Thiel
In reply to this post by Nicolas Di Césaré
#define NOMINMAX

before (directly or indirectly) including WinDef.h usually solves this kind
of problems (but may spawn others with eg. ATL headers, so you may need to
define some replacements).


Regards,

Jens.

--
/* Jens Thiel * Stochastix GmbH, Germany * +49-700-STOCHASTIX */



> -----Original Message-----
> From: Nicolas Di Césaré
> Sent: Wednesday, October 31, 2001 11:40 AM
> To: QuantLib Users
> Subject: [Quantlib-users] Some trouble with qldefines.hpp
>
>
> Hi all,
>
> I have some trouble with numeric_limits<>::max() under visual
> C++. It conflicts with macro max.



Reply | Threaded
Open this post in threaded view
|

RE: Some trouble with qldefines.hpp

Nicolas Di Césaré
En réponse à Jens Thiel <[hidden email]>:

> #define NOMINMAX
>
> before (directly or indirectly) including WinDef.h usually solves this
> kind
> of problems (but may spawn others with eg. ATL headers, so you may need
> to
> define some replacements).

Hi Jens,

Do you know if WinDef.h is included somewhere in standart C++ headers?
because I don't include that file :-(

I add NOMINMAX in the preprocessor definitions and it works fine if I redefine
min/max functions.

I think that the 1st solution is better because we just have to change
qldefines.hpp file. With the second one, we have to define NOMINMAX in each new
project.

Do you have another idea?

Thanks,

Nicolas


 



--
Nicolas Di Césaré
http://acm.emath.fr/~dicesare


Reply | Threaded
Open this post in threaded view
|

RE: Some trouble with qldefines.hpp

Jens Thiel
> -----Original Message-----
> From: Nicolas Di Césaré
>
> Do you know if WinDef.h is included somewhere in standart C++ headers?
> because I don't include that file :-(
>

it is usually included indirectly by windows.h and others.

> I add NOMINMAX in the preprocessor definitions and it works fine
> if I redefine min/max functions.
>
> I think that the 1st solution is better because we just have to change
> qldefines.hpp file. With the second one, we have to define
> NOMINMAX in each new project.
>

Since defining min()/max() macros is wrong (should have been _min or MIN if
any), I think it's best to turn it off completely and replace it with
template functions. That way it should not break anything (and if something
breaks there will be some very good reason...). Thats why M$ added NOMINMAX.

Of course, using (min)() prevents macro expansion, so you can go with that,
if you are sure that you (and all of your colleagues now and forever) will
use (min)() properly...

> Do you have another idea?
>

Why not having a site specific include file that you will use in all of your
projects?


Regards,

Jens.

--
/* Jens Thiel * Stochastix GmbH, Germany * +49-700-STOCHASTIX */



Reply | Threaded
Open this post in threaded view
|

RE: Some trouble with qldefines.hpp

Jens Thiel
In reply to this post by Nicolas Di Césaré
>
> Do you have another idea?
>

i just did some research and think that <algorithm> maybe your candidate.
You may also have a look at the following thread from the boost mailing list
(and, if not already, visit http://www.boost.org/)

http://groups.yahoo.com/group/boost/message/3810

Regards,


Jens.

--
/* Jens Thiel * Stochastix GmbH, Germany * +49-700-STOCHASTIX */



Reply | Threaded
Open this post in threaded view
|

RE: Some trouble with qldefines.hpp

Luigi Ballabio-4
In reply to this post by Jens Thiel
At 12:49 PM 11/2/01 +0100, Jens Thiel wrote:
> > -----Original Message-----
> > From: Nicolas Di Césaré
>
> > I add NOMINMAX in the preprocessor definitions and it works fine
> > if I redefine min/max functions.
> >
> > I think that the 1st solution is better because we just have to change
> > qldefines.hpp file. With the second one, we have to define
> > NOMINMAX in each new project.

We might define it in qldefines.hpp---or rather in config.msvc.hpp which
config.hpp includes if the compiler is Visual C++. I'm not sure how solid
that would be, though: it would work fine if we always write

#include <ql/qldefines.hpp>
#include <algorithm>

but what if one forgets and writes

#include <algorithm>
#include <ql/qldefines.hpp>

Should we rely on inclusion order to make it work? Hmm...

>Since defining min()/max() macros is wrong (should have been _min or MIN if
>any), I think it's best to turn it off completely and replace it with
>template functions. That way it should not break anything (and if something
>breaks there will be some very good reason...). Thats why M$ added NOMINMAX.
>
>Of course, using (min)() prevents macro expansion, so you can go with that,
>if you are sure that you (and all of your colleagues now and forever) will
>use (min)() properly...

That should be ensured by using the QL_MIN and QL_MAX macros which expand
to the right definition depending on the compiler. In the VC++ case, they
expand to std::_cpp_min and std::_cpp_max which are the template min and
max we all know and love.

>Why not having a site specific include file that you will use in all of your
>projects?

We have it already. That is the purpose of qldefines.hpp.

Bye,
         Luigi



Reply | Threaded
Open this post in threaded view
|

RE: Some trouble with qldefines.hpp

Nicolas Di Césaré
En réponse à Luigi Ballabio <[hidden email]>:

> At 12:49 PM 11/2/01 +0100, Jens Thiel wrote:

> We might define it in qldefines.hpp---or rather in config.msvc.hpp which
>
> config.hpp includes if the compiler is Visual C++. I'm not sure how
> solid
> that would be, though: it would work fine if we always write
>
> #include <ql/qldefines.hpp>
> #include <algorithm>
>
> but what if one forgets and writes
>
> #include <algorithm>
> #include <ql/qldefines.hpp>

After reading boost mailing list, I think we have to mix the both ideas. In
qldefines.hpp we can check if NOMINMAX is defined and if not
print a message asking user to define it in the preprocessor definitions.

#if defined HAVE_LIMITS
#if !defined(NOMINMAX)
#pragma message("Add NOMINMAX to preprocessor definitions ...")
# undef min
# undef max
namespace std
{
 template<class T> inline const T &max(const T &x, const T &y)
    { return x < y ? y : x; }
 template<class T> inline const T &min(const T &x, const T &y)
    { return y < x ? y : x; }
}
    #include <limits>

...




--
Nicolas Di Césaré
http://acm.emath.fr/~dicesare