ByoTic
ByoTic

Reputation: 333

Preprocessor define functions expected an expression

I have tried to do this kind of define:

#define Math.Pow(a,b) (int result=1; for (int i=0; i<b; i++) result*=a; return result;)

and When I'm using Math.Pow(a,b) in the code, I get an error:

expected an expression.

I tried to put this definition in another function, such as

int Power(int a, int b)
{int result=1; for (int i=0; i<b; i++) result*=a; return result;}

and then

#define Math.Pow(a,b) (Power(a,b))

but I got the same error.

Upvotes: 1

Views: 3578

Answers (3)

Dimitrios Bouzas
Dimitrios Bouzas

Reputation: 42929

Discussion

When using macros the preprocessor runs just before the compiler and replaces your macros in code with the aliased text you specified.

Your first problem is that the name of your macro contains a dot .. This is not allowed because the name of a macro is an identifier. Identifier names are not allowed to use the dot character because the . is used for the operator. (i.e., the dot operator). So the compiler rightfully complains.

Lets say that we overcome this problem by using a legitimate name for your macro, say Math_Pow.

Now lets say that you have the folowing piece of code:

#define Math_Pow(a,b) (int result=1; for (int i=0; i<b; i++) result*=a; return result;)

int main () {
  Math_Pow(1, 3);
}

Now, when your macro is going to be replaced by the preprocessor with the aliased text in the code above, the code feed to the compiler is going to be:

int main () {
  (int result=1; for (int i=0; i<b; i++) result*=a; return result;)
}

The above is not legal C++, so the compiler again complains.

Now lets say that instead of parentheses we use curly brackets (e.g,. #define Math_Pow(a,b) {int result=1; for (int i=0; i<b; i++) result*=a; return result;})

Now the code becomes:

int main () {
  {int result=1; for (int i=0; i<b; i++) result*=a; return result;}
}

The above code is correct syntactically, however it has a logical flaw. It returns result from main. This means that if you state this corrected macro in a function, this function will return and this is something that obviously you don't wan't this macro to do.

Solutions

  1. Standard math library already has version of pow.
  2. Define your macro as an inline function:

  inline int Power(int a, int b) {
    int result = 1; 
    for (int i = 0; i < b; ++i) result *= a; 

    return result;
  }

Upvotes: 1

Jack
Jack

Reputation: 2273

In addition to the issue of . in a name, your macro introduces multiple statements that are grouped with parentheses, e.g. (statement; statement; statement;) That is not legal C/C++ syntax. You can however, use the comma operator to evaluate multiple separate expressions (but not execute multiple arbitrary statements). There are much better ways of doing what you're trying to do however.

Upvotes: 1

Remy Lebeau
Remy Lebeau

Reputation: 598309

You cannot put a . character in a macro name. Even if you could, a return statement inside a macro does not return a value from the macro itself. Remember that a macro is just a text replacement before the compiler is invoked, so the return will apply to the calling code, which is not what you really want in this situation.

To do what you are attempting, use a templated function instead:

struct Math
{
    template<typename T>
    static T Power(T a, T b)
    {
        T result = 1;
        for (int i = 0; i < b; ++i)
            result *= a;
        return result;
    }
};

Or:

namespace Math
{
    template<typename T>
    T Power(T a, T b)
    {
        T result = 1;
        for (int i = 0; i < b; ++i)
            result *= a;
        return result;
    }
}

Either way, you can then call it like this:

Math::Power(value1, value2);

Upvotes: 3

Related Questions