Home > OS >  Can ";" be added after "#define" And whether variables can be used in it
Can ";" be added after "#define" And whether variables can be used in it

Time:12-10

A topic has the following code, which is required to indicate the location of the error.

#include<iostream>
#define PT 3.5;
#define S(x) PT*x*x
    
void main() {
    int a = 1, b = 2;
    std::cout << S(a   b);
}

I think ";" caused this problem ,and deleted ';' the post compilation test can get the correct results.But the teacher thinks that variables cannot be used in macro definition. I'm not sure who is right.

I've seen a lot of answers, but what I want to know is not whether it's reasonable to write like this, but what causes the program error in the end.

Add ';' after '#define' Not particularly good, but the compilation can pass. "#define" can also allow variables to appear. So the final error reason is "* a b"?

CodePudding user response:

There's a couple of problems. Yes, the PT will expand to 3.5; and cause a syntax error. Change that to:

#define PT 3.5

The other issue is that S(a b) will expand to PT*a b*a b which is clearly not what you want. As a matter of convention, macros that perform arithmetic should wrap any expandable parts in parentheses, and the entire macro should also be in parentheses:

#define S(x) ((PT)*(x)*(x))

This ensures that you don't have to worry about expanded expressions wreaking havoc due to operator precedence rules.

Regarding the comment about your teacher...

the teacher thinks that variables cannot be used in macro definition

It's possible that they are talking about the fact that x is just a placeholder for expansion. If you pass a b and use x twice, then a b will be evaluated twice. Imagine if you called S( a)... You'd get PT*( a)*( a)

It's usually more appropriate to just write a function, and that avoids problems like the above.

double S(int x) {
    return PT * x * x;
}

Or even:

template<class T>
double S(T x) {
    return PT * x * x;
}

CodePudding user response:

You can't put a semicolon after PT because your macro S(X) PT*x*x would get processed to 3.5;*x*x

Your S(x) macro is breaking because the semicolons breaks it into 2 statements. First is 3.5; and the second one is *x*x hence why you get the error.

To make it work you simply need to remove the ; in your definition of PT

CodePudding user response:

Macros are just text substitution, so you can do pretty much anything you want, as long as the result of the substitution is valid code. So the literal answer to "Can ';' be added after #define" is yes, but the result might not work.

#define calc(x) ((x) * (x));

void f() {
    int g = 3;
    int h = calc(g);
}

The result of the macro expansion is

int h = ((g) * (g));;

That's valid code; the second semicolon marks the end of an empty expression, just as if it had been written

int h = ((g) * (g));
;

That's bad style, of course, and it could cause problems in other contexts, so the "right" way to use that macro would be

    int h = calc(g)

That way, the text that results from the macro expansion would only have one semi-colon. But that looks weird, and the macro really shouldn't have that semicolon in it.

As to using variables, again, it depends on what the result of the text substitution is.

#define calc (x) * (x)

void f() {
    int x = 3;
    int y = calc;
}

That's okay; the code is equivalent to

void f() {
    int x = 3;
    int y = (x) * (x);
}

On the other hand, this isn't okay:

void f() {
    int b = 3;
    int y = calc;
}

It doesn't work because there is no x there. So this macro has vary limited usefulness; there are rare situations where it might be appropriate, but, in general, it's a bad idea.

  •  Tags:  
  • c
  • Related