Thread: Problem with macros and templates

  1. #1
    Registered User
    Join Date
    Oct 2011
    Posts
    3

    Problem with macros and templates

    I'm trying to get two VS2008 projects (of which neither are written by me) that separately compiles just fine, to work together.

    When I include a header from the first project in the second, I get this error:

    Code:
     ... Defs.hpp(195) : warning C4002: too many actual parameters for macro 'min'
    Here is the code that generates the error

    Code:
    #define FW_CUDA_FUNC     __device__ __inline__
    
    #define FW_SPECIALIZE_MINMAX(TEMPLATE, T, MINVAL, MAXVAL) \
        TEMPLATE FW_CUDA_FUNC T min(T a, T b) { return MINVAL; } \
        TEMPLATE FW_CUDA_FUNC T max(T a, T b) { return MAXVAL; } \
        TEMPLATE FW_CUDA_FUNC T min(T a, T b, T c) { return min(min(a, b), c); } \
        TEMPLATE FW_CUDA_FUNC T max(T a, T b, T c) { return max(max(a, b), c); } \
        TEMPLATE FW_CUDA_FUNC T min(T a, T b, T c, T d) { return min(min(min(a, b), c), d); } \
        TEMPLATE FW_CUDA_FUNC T max(T a, T b, T c, T d) { return max(max(max(a, b), c), d); } \
        TEMPLATE FW_CUDA_FUNC T min(T a, T b, T c, T d, T e) { return min(min(min(min(a, b), c), d), e); } \
        TEMPLATE FW_CUDA_FUNC T max(T a, T b, T c, T d, T e) { return max(max(max(max(a, b), c), d), e); } \
        TEMPLATE FW_CUDA_FUNC T min(T a, T b, T c, T d, T e, T f) { return min(min(min(min(min(a, b), c), d), e), f); } \
        TEMPLATE FW_CUDA_FUNC T max(T a, T b, T c, T d, T e, T f) { return max(max(max(max(max(a, b), c), d), e), f); } \
        TEMPLATE FW_CUDA_FUNC T min(T a, T b, T c, T d, T e, T f, T g) { return min(min(min(min(min(min(a, b), c), d), e), f), g); } \
        TEMPLATE FW_CUDA_FUNC T max(T a, T b, T c, T d, T e, T f, T g) { return max(max(max(max(max(max(a, b), c), d), e), f), g); } \
        TEMPLATE FW_CUDA_FUNC T min(T a, T b, T c, T d, T e, T f, T g, T h) { return min(min(min(min(min(min(min(a, b), c), d), e), f), g), h); } \
        TEMPLATE FW_CUDA_FUNC T max(T a, T b, T c, T d, T e, T f, T g, T h) { return max(max(max(max(max(max(max(a, b), c), d), e), f), g), h); } \
        TEMPLATE FW_CUDA_FUNC T clamp(T v, T lo, T hi) { return min(max(v, lo), hi); }
    
    
    FW_SPECIALIZE_MINMAX(template <class T>, T&, (a < b) ? a : b, (a > b) ? a : b)
    Row 195 is the last row in the code above.

    As both project compile separately, I'm thinking this has something to do with (pre?)compiler options. I've tried to isolate the error by looking at differences in settings between the two projects, but I don't really know where to look.

    Any ideas would be greatly appreciated!

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Make them template functions instead of macros.

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Never create macros with lower-case names, especially for common names like min and max!
    Template functions obey scope, at least, and don't give incomprehensible syntax errors everywhere.
    Last edited by Elysia; 10-25-2011 at 11:53 AM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #4
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by Elysia View Post
    Never create macros with lower-case names, especially for common names like min and max!
    That said, the solution would be, like whiteflags said, to make them template functions. They obey scope, at least, and don't give incomprehensible syntax errors everywhere.
    That's overselling them. Template errors can be pretty bad too.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Yes, but they don't give syntax errors
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Template functions were my suggestion because that looks like what the poster wants to use. I don't need to sell my advice and I don't want anyone doing it for me.

  7. #7
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Actually, looking at the OP with more scrutiny, the code is creating a bunch of template functions.

    The problem seems to be that one project is creating min as a macro, and one as a template. This one is creating it as a template, so look at the other one. Probably, you will want to remove the macro.

    Search for "#define min" and you may find it.
    Last edited by King Mir; 10-25-2011 at 12:03 PM.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  8. #8
    Registered User
    Join Date
    Oct 2011
    Posts
    3
    Quote Originally Posted by Elysia View Post
    Never create macros with lower-case names, especially for common names like min and max!
    That said, the solution would be, like whiteflags said, to make them template functions. They obey scope, at least, and don't give incomprehensible syntax errors everywhere.
    I think the macro generates templated min/max functions, so in the end there are no lowercase macros.

    Anyway, I have a theory on where the problem might be.
    PREVIOUSLY: I think the problem might be that one of the projects include <algorithm>, which defines templated min/max functions.
    EDIT:When I look up min() or max() i VS, they are defined as macros in WinDef.h. The problem is that no file in the project seems to include WinDef.h, at least not directly. Can this be solved with namespaces somehow?
    Last edited by Nickedname; 10-25-2011 at 12:28 PM.

  9. #9
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    That's not what it looks like; I'd expect a different error message, if one at all. Creating a min function in the global namespace should not conflict with namespace std. Now it could be a non conforming standard library implementation.

    As a quick fix, you could write #undef min above the code you posted. However, this may have other side effects.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  10. #10
    Registered User
    Join Date
    Oct 2011
    Posts
    3
    Quote Originally Posted by King Mir View Post
    That's not what it looks like; I'd expect a different error message, if one at all. Creating a min function in the global namespace should not conflict with namespace std. Now it could be a non conforming standard library implementation.

    As a quick fix, you could write #undef min above the code you posted. However, this may have other side effects.
    Thanks! The #undef min and #undef max fixed it.

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I admit I didn't read the original problem properly, but what you just saw is a prime example of why lower-case names for macros should not be used.
    According to what I understand, you didn't do that, so that's good. But at least now you got to experience what devastation it can cause.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    639
    You could also define NOMINMAX before including windows.h, because that's always the problem when there's shenanigans with min or max identifiers.

  13. #13
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by adeyblue View Post
    You could also define NOMINMAX before including windows.h, because that's always the problem when there's shenanigans with min or max identifiers.
    That sounds like a better solution, if that is indeed the source of the problem.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by adeyblue View Post
    You could also define NOMINMAX before including windows.h, because that's always the problem when there's shenanigans with min or max identifiers.
    Maybe they should rename that

    #define NO_NONSENSE
    or
    #define GET_RID_OF_STUPIDITY
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    this problem could much more easily be solved by declaring the functions like so:

    Code:
    template<typename T>
    T getMin(std::initializer_list<T> theList);
    
    template<typename T>
    T getMax(std::initializer_list<T> theList);
    then you would call them like so:

    Code:
    int theMax = getMax({1, 3, 5, 7, 9, 0});
    double theMin = getMin({1.0, 3.0, 5.0, 7.0, 9.0, 0.0});

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem with templates
    By manasij7479 in forum C++ Programming
    Replies: 7
    Last Post: 10-05-2011, 07:08 PM
  2. problem with program number divisible by 10? using macros
    By MarjunC in forum C++ Programming
    Replies: 5
    Last Post: 06-23-2010, 05:43 AM
  3. Problem with macros..
    By sanddune008 in forum C Programming
    Replies: 4
    Last Post: 07-07-2009, 02:00 AM
  4. Macros inside of macros
    By Chewie8 in forum C Programming
    Replies: 2
    Last Post: 02-24-2008, 03:51 AM
  5. Templates and Macros plus more...
    By Monkeymagic in forum C++ Programming
    Replies: 8
    Last Post: 01-20-2007, 05:53 PM