Registered Member
|
Unfortunately windows.h decided to #define min and max. This can lead to numerous difficult to diagnose compiler errors on windows.
In most cases however simply wrapping functions named min or max with parenthesis prevents macro expansion and allows to code to function as intended. I haven't done a full fix/test but below is the minimal patch required for my project to compile.
Last edited by bjacob on Mon Jan 19, 2009 1:17 pm, edited 1 time in total.
|
Registered Member
|
You can use the preprocessor define NOMINMAX to get rid of min/max defined in #windows.h. I had this problem in another project, NOMINMAX worked just fine.
|
Moderator
|
Do you really need these min/max function macros ? I'd rather recommend to define NOMINMAX before including windows.h.
EDIT: stefanTUD: you're too fast
Last edited by ggael on Wed Jan 14, 2009 7:40 pm, edited 1 time in total.
|
Registered Member
|
Maybe we should allow ourselves to #undef min and max in Eigen, like we already #undef a few polluting symbols?
Join us on Eigen's IRC channel: #eigen on irc.freenode.net
Have a serious interest in Eigen? Then join the mailing list! |
Registered Member
|
For my project we can get away with NOMINMAX but some projects can't so I thought a solution that is applicable to even projects that rely on windows.h's use of min and max macros would be preferable.
|
Registered Member
|
There are only two solutions I'm comfortable with, in order of preference: First, wrapping the min and max usages in eigen with parenthesis to prevent macro expansion. Second, documenting the issue and instructing the user to define NOMINMAX since this really isn't eigen's bug.
I'm not really comfortable with eigen doing "#undef min" and "#undef max" or "#define NOMINMAX" since eigen is a middleware product and this solution assumes specifics about what other libraries are being used alongside it.
Last edited by kfriddile on Wed Jan 14, 2009 8:32 pm, edited 1 time in total.
|
Registered Member
|
Is it really a problem if we #undef min and max?
First, we have to #undef a few stupid symbols anyway, e.g. "vector" that is defined in altivec.h. Second, a source file #including Eigen is C++, not C, so if they want min they should use std::min. It is really brain dead that windows.h defines min even with __cplusplus. If we force people to use std::min instead of a macro, we're doing them a service, no?[hr] More arguments: C and C++ are two distinct language and windows' way of defining min and max is in plain conflict with C++ standard lib, so I don't think we should honor that. the solution with (min) obfuscates our own source code and there'll always be a place where we forgot the () since ggael and me are on GNU so if we take this way it's going to become another annoying recurrent issue...
Last edited by bjacob on Wed Jan 14, 2009 9:13 pm, edited 1 time in total.
Join us on Eigen's IRC channel: #eigen on irc.freenode.net
Have a serious interest in Eigen? Then join the mailing list! |
Registered Member
|
I agree that std::min/max should be used where appropriate however you may not be doing someone a service if they have a legacy code base they cannot refactor.
I understand not wanting to obfuscate your source code to work around a shortsighted feature of an OS header. In that case I would prefer a note in the documentation stating that eigen only supports compiling in translation units where windows.h is included if NOMINMAX was defined prior to the inclusion of windows.h. This solution is incompatible with legacy code bases without refactoring but so is the #undef solution. Using #undef leaks to user code and should be avoided in libraries if at all possible. FWIW Other projects have had this issue too. Boost chose to disable macro expansion[1]. To alleviate the maintenance issue you brought up they have created an automated tool[2] which detects unprotected calls to min and max. [1] http://www.boost.org/development/requir ... rogramming [2] http://www.boost.org/doc/libs/1_37_0/to ... index.html https://svn.boost.org/trac/boost/browse ... s/inspect/ |
Registered Member
|
There is a simple trick that we can do. We already have header files DisableMSVCWarnings.h included at the beginning of Eigen public headers, and EnableMSVCWarnings included at the end.
We could (rename them and) let them do something like that: at the beginning, #ifdef min #define min_was_defined #endif #ifdef max #define max_was_defined #endif and then at the end, #ifdef min_was_defined #define min(x,y) blabla....... // copy the junk from windows.h #endif .... if different OS headers have the same problem we can still handle that with more #ifdef... What's your opinion?
Join us on Eigen's IRC channel: #eigen on irc.freenode.net
Have a serious interest in Eigen? Then join the mailing list! |
Registered Member
|
Another possibility, which has the advantage of locality: it only needs to be done once at the beginnig of Eigen/Core :
// to put in root namespace, after #including a standard header that defines std::min #ifdef min #undef min using std::min; #endif This however relies on the assumption that std::min is actually able to handle all situations that windows's min handles: to be checked.
Join us on Eigen's IRC channel: #eigen on irc.freenode.net
Have a serious interest in Eigen? Then join the mailing list! |
Registered Member
|
Finally we just #error if min or max are defined with a hopefully useful message. Tell me if this can be improved.
Join us on Eigen's IRC channel: #eigen on irc.freenode.net
Have a serious interest in Eigen? Then join the mailing list! |
Registered Member
|
That seems reasonable. |
Registered users: Bing [Bot], Evergrowing, Google [Bot], rblackwell