4

While researching solutions to the windows min/max macro problem, I found an answer that I really like but I do not understand why it works. Is there something within the C++ specification that says that macro substitution doesn't occur within parens? If so where is that? Is this just a side effect of something else or is the language designed to work that way? If I use extra parens the max macro doesn't cause a problem:

(std::numeric_limits<int>::max)()

I'm working in a large scale MFC project, and there are some windows libraries that use those macros so I'd prefer not to use the #undef trick.

My other question is this. Does #undef max within a .cpp file only affect the file that it is used within, or would it undefine max for other compilation units?

chris
  • 60,560
  • 13
  • 143
  • 205
shawn1874
  • 1,288
  • 1
  • 10
  • 26
  • 2
    `#undef X` only removes the definition of `X` until the end of the compilation of the current file (or until `X` is #define'd again, of course). – mah Apr 11 '14 at 20:56
  • 1
    You could try `#define NOMINMAX` before including Windows.h to disable those macros. Not sufe it that interferes with anything MFC expects to be available. – Retired Ninja Apr 11 '14 at 21:07
  • NOMINMAX will not work. There are other libs and headers that require min and max. In my case, it is an existing project so I don't want to be undefining things that are used by other parts of the project. – shawn1874 Apr 11 '14 at 22:11

1 Answers1

10

Function-like macros only expand when the next thing after is an opening parenthesis. When surrounding the name with parentheses, the next thing after the name is a closing parenthesis, so no expansion occurs.

From C++11 § 16.3 [cpp.replace]/10:

Each subsequent instance of the function-like macro name followed by a ( as the next preprocessing token introduces the sequence of preprocessing tokens that is replaced by the replacement list in the definition (an invocation of the macro).

To answer the other question, preprocessing happens before normal compilation and linking, so doing an #undef in an implementation file will only affect that file. In a header, it affects every file that includes that header.

chris
  • 60,560
  • 13
  • 143
  • 205