We help IT Professionals succeed at work.

Visual studio: using the min max macros in some places but not others.

3,616 Views
Last Modified: 2013-12-14
Hello,

I'm using the libpqxx C++ wrapper for postgresql database server's libpq C API in an MFC application.

I make the following pre-processor directives in my myapp.cpp, which is required by the wrapper:

#include <cassert>

#include <iostream>

#include <pqxx/pqxx>

using namespace PGSTD;

using namespace pqxx;

I then instantiate a connection object somewhere:

connection C;

This returns the following error:

1>c:\libpqxx-2.6.9\include\pqxx\compiler-public.hxx(34) : fatal error C1189: #error :  "Oops: min() and/or max() are defined as preprocessor macros.  Define NOMINMAX macro before including any system headers!"

So, I #define NOMINMAX in stdafx.h . This solves the problem, but breaks compilation in other ways:
1>c:\documents and settings\user\my documents\visual studio 2005\projects\lustre\lustre\reportctrl.cpp(637) : error C3861: 'max': identifier not found
1>c:\documents and settings\user\my documents\visual studio 2005\projects\lustre\lustre\reportctrl.cpp(1002) : error C3861: 'max': identifier not found
1>c:\documents and settings\user\my documents\visual studio 2005\projects\lustre\lustre\reportctrl.cpp(1140) : error C3861: 'max': identifier not found
1>c:\documents and settings\user\my documents\visual studio 2005\projects\lustre\lustre\reportctrl.cpp(1152) : error C3861: 'max': identifier not found

reportctrl.cpp is dependent on the macro.

This is the pertinent part of libpqxx:

/* Work around a particularly pernicious and deliberate bug in Visual C++:
 * min() and max() are defined as macros, which can have some very nasty
 * consequences.  This compiler bug can be switched off by defining NOMINMAX.
 *
 * We don't like making choices for the user and defining environmental macros
 * of our own accord, but in this case it's the only way to compile without
 * incurring a significant risk of bugs--and there doesn't appear to be any
 * downside.  One wonders why this compiler wart is being maintained at all,
 * since the introduction of inline functions back in the 20th century.
 */

#if defined(min) || defined(max)

#error "Oops: min() and/or max() are defined as preprocessor macros.\
  Define NOMINMAX macro before including any system headers!"

#endif

How can I satisfy reportctrl's need for the minmax macros while satisfying libpqxx's need to not have the minmax macros? Can I use the NOMINMAX macro as and when I choose?

Regards,
Sternocera
Comment
Watch Question

CERTIFIED EXPERT

Commented:
Hi sternocera,

try to #define NOMINMAX directly befor
#include <pqxx/pqxx>
and maybe #undef it again afterwards.

hope that helps,

ZOPPO
AndyAinscowFreelance programmer / Consultant
CERTIFIED EXPERT

Commented:
#define NOMINMAX in stdafx.h

Rather than that - define it just in the .cpp files where you are using this class

Author

Commented:
Andy: If I do that, I get this error:
1>c:\libpqxx-2.6.9\include\pqxx\compiler-public.hxx(34) : fatal error C1189: #error :  "Oops: min() and/or max() are defined as preprocessor macros.  Define NOMINMAX macro before including any system headers!"
CERTIFIED EXPERT

Commented:
Did you define it before you include <pqxx/pqxx>?

Author

Commented:
Yes.
CERTIFIED EXPERT

Commented:
Maybe you somewhere else inclulde something from pqxx?

Author

Commented:
No, I don't.

Author

Commented:
It does say "Define NOMINMAX macro before including any system headers!"
CERTIFIED EXPERT
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION
AndyAinscowFreelance programmer / Consultant
CERTIFIED EXPERT
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION

Author

Commented:
This (reportctrl.cpp) is a file I downloaded off code project which provides certain "out of the box" functionality - a full featured list control. I did not write it myself.

I guess I could take a look at it and try and resolve the problem, but if much stock MFC code uses these macros, it would be difficult to continually change the code as I introduced that stock code.

It would be preferable to try and use the pre-processor directive, while somehow still using the macro in certain places,

Thanks

Author

Commented:
I tried adding #undef NOMINMAX to the header of ReportCtrl. It didn't make a difference,
Thanks

Author

Commented:
Yeah, using the STL functions rather then the macros makes absolutely no difference.

Thanks a lot guys.
CERTIFIED EXPERT

Commented:
You're welcome ... nice we could help you.

Have a nice day,

best regards,

ZOPPO

Author

Commented:
I just wonder why min and max are macros in the first place...

It's a visual studio quirk.
CERTIFIED EXPERT

Commented:
Well, they are defined somewhere when including <windows.h> - this include file is one of the most basic includes you need in windows. STL is a C++ library which is often not used when developing windows applications. Pure windows API even is not C++. Without C++ there's no other chance to implement min/max for different types instead of using macros.
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.