Popular header that misused function-like macro max

Viewed 92

On page 1057 of Programming Principles and Practice Using C++, Second Edition, Bjarne Stroustrup discusses a problem with Function-like macros.

He starts with an example. The macro below:

#define MAX(x, y) ((x)>=(y)?(x):(y))

used in the following line:

double dd = MAX(aa++, 2);

substitutes to become:

double dd = ((aa++)>=(2)?(a++):(2));

About this example, he explains:

On the other hand, not all the parentheses in the world could save the second expansion. The macro parameter x was given the value aa++, and since x is used twice in MAX, a can get incremented twice. Don't pass an argument with a side effect to a macro.

As it happens, some genius did define a macro like that and stuck it in a popular header file. Unfortunately, he also called it max, rather than MAX, so when the C++ standard header defines

template<class T> inline T max(T a, T b) {return a<b?b:a;}

the max gets expanded with the arguments T a and T b and the compilers sees

template<class T> inline T ((T a)>=(T b)?(T a):(T b)) {return a<b?b:a;}

The compiler error messages are "interesting" and not very helpful. In an emergency, you can "undefine" a macro:

#undef max.

Bjarne Stroustrup's story sounds like it would be a well-known one in the C++ community, however, I couldn't find anything more written about it online. Bjarne Stroustrup's frustration here suggests that this particular header created backwards compatibility problems developing C++.

What was the header Bjarne refers to in his story?

0 Answers
Related