Strange behaviour of macros C/C++

久未见 提交于 2019-11-27 16:19:10

Macros are (relatively simple) textual substitutions.

Use parentheses in your definitions (both to enclose the macro itself and the macro arguments):

#define PI (atan(1) * 4)
#define radians(deg)  ((deg) * PI / 180)
#define degrees(rad)  ((rad) * 180 / PI)

First, cmath defines M_PI, use that.

Second, cpp macros do textual substitution. Which mean that this:

#define PI atan(1) * 4
a = 1 / PI;

will be turned into this:

a = 1 / atan(1) * 4;

before the c/c++ compiler gets a chance to see your code, and it will treat it equivalent to this:

a = (1 / atan(1)) * 4;

which is not what you want.

Your define should look like this:

#define PI (atan(1) * 4)

and everything should be fine.

This is not really strange behaviour, but well documented behaviour of the c-preprocessor.

You should search the web for other pitfalls with macros. (hint: parameter passing)

You should use parenthesis for your macros to specify precedence. In addition to that, i think in many cases math.h will define PI for you

Macros just do text substitution without regard for context, so what you wind up with is:

cout << "PI, in degrees: " << atan(1) * 4 * 180 / atan(1) * 4 << endl;

Note the distinct lack of parens around the second atan(1) * 4, causing it to divide only by atan(1) and then multiply by 4.

Instead, use inline functions and globals:

const double PI = atan(1) * 4;
double radians(double deg) { return deg * PI / 180; }
double degrees(double rad) { return rad * 180 / PI; }

Also good practice: Add brackets around all your parameters:

#define radians(deg)  ((deg) * PI / 180)

because the expression you pass as parameter might include operators, too.

Or even better: Use (inline-) functions instead of macros, to avoid surprises with sideeffects when a parameter is evaluated multiple times like here:

#define sqr(x)  ((x) * (x))

The only disadvantage you get with inline functions: You can define them for one type, only (unless you use C++ templates)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!