user59988
user59988

Reputation:

C Error - macro "max" requires 2 arguments, but only 1 given

While trying to compile the code below:

template <class T>
struct scalar_log_minimum {
    public:
        typedef T value_type;
        typedef T result_type;
        static
            result_type initial_value(){
                return std::log(std::numeric_limits<result_type>::max());
        }
        static
            void update(result_type& t, const value_type& x){
                if ( (x>0) && (std::log(x)<t) ) t = std::log(x);
        }
    };

I got the following error :

functional_ext.hpp:55:59: macro "max" requires 2 arguments, but only 1 given

Here "max" is not a macro, right? Then what is this error? BTW, I am using Visual Studio 2005.

Also what does 55:59 mean - 55 is the line number 59?

Upvotes: 6

Views: 13027

Answers (4)

jwfearn
jwfearn

Reputation: 29627

As others have noted, including windows.h is probably your problem. Microsoft provides a means to "turn off" parts of windows.h with preprocessor symbols. You can define these symbols as part of your build or directly in code.

Using preprocessor symbols to conditionally skip sections of windows.h may or may not be considered elegant but in the general case it is an easier, more general and more scalable solution than #undef.

Here's how to skip defining min or max as macros:

#define NOMINMAX
#include <windows.h>

Note that many include files will, at some point, include windows.h. In such cases setting up your defines at a more global level may be more convenient.

If you search through windows.h, you can find a bunch of other preprocessor symbols (e.g., NOOPENFILE, NOKANJI, NOKERNEL and many others) that can often be useful.

Upvotes: 3

user52875
user52875

Reputation: 3058

I find the many #defines that you encounter once you included windows.h very disturbing (not only max and min, but I also had problems with other generic words like Rectangle if I'm not mistaken). Therefore, I have developed the habit to include windows.h only when absolutely necessary, and never in header files. This reduces the pain to a small number of C++ files that are platform-specific.

Unfortunately some boost libraries (I believe thread and asio) do include windows.h in their headers, and I still run into this kind of silly problems from time to time.

My solution for the remainder of the situations where this causes problems is to #undef the problematic symbols after the inclusion of the header files.

Upvotes: 7

Johannes Schaub - litb
Johannes Schaub - litb

Reputation: 507055

It's a macro called max that gets into the way as Adam explained. Another solution (more a "hotfix") may be to put parentheses around the function, to prevent it from being seen as a macro invocation:

return std::log((std::numeric_limits<result_type>::max)());

Upvotes: 2

Adam Rosenfield
Adam Rosenfield

Reputation: 400344

You're including a header file somewhere that #defines max as a macro. The best solution would be to figure out where it's being defined, and inhibit it from being defined if possible. Alternatively, you could just #undef it:

#include <evil_header_which_defines_max.h>
#undef max

Upvotes: 7

Related Questions