Tree
Tree

Reputation: 145

Why am I getting errors while compiling this code and how to fix them?

The program I'm trying to write includes a macro to round a real number to the nearest integer and a function which uses that macro to round an array of real numbers.

Here's the program:

#include <stdio.h>

#define SIZE 256
#define round(N) {  return (N >=0)? (int)(N+0.5) : (int)(N-0.5) ; }

void round_array(int a[])
{
   int i;
   for(i=0; i <SIZE; i++)
   {
       a[i] = round(a[i]);
   }
}                                                     

int main()
{

    return 0;
}

While compiling, I'm getting these errors:

 round.c: In function ���round_array���:
 round.c:4:18: error: expected expression before ���{��� token
 #define round(N) {  return (N >=0)? (int)(N+0.5) : (int)(N-0.5) ; }
                  ^
round.c:11:15: note: in expansion of macro ���round���
        a[i] = round(a[i]);
               ^
round.c: At top level:

Why am I getting these errors and how can I fix them?

Upvotes: 0

Views: 121

Answers (5)

Lundin
Lundin

Reputation: 214300

If you insist on writing this yourself, you should replace the icky macro with a safer, cleaner function:

inline int int_round (double d)
{
  return (int) ( d >= 0 ? d+0.5 : d-0.5 );
}

This should yield the very same machine code.

Upvotes: 1

dmi
dmi

Reputation: 1479

Because after preprocessing, your code will look similar to that:

a[i] = {  return (a[i] >=0)? (int)(a[i]+0.5) : (int)(a[i]-0.5) ; }

If you like to stick to macro, declare it as:

#define round(N) ((N) >=0)? (int)((N)+0.5) : (int)((N)-0.5)

But this is still not really correct because of int/float mixing. That is however already a different topic.

Upvotes: 2

Some programmer dude
Some programmer dude

Reputation: 409356

Macro-replacement is basically what it sounds like, it replaces the macro with the body of the macro, quite literally.

So when you have

a[i] = round(a[i]);

It will be replaced by

a[i] = {  return (a[i] >=0)? (int)(a[i]+0.5) : (int)(a[i]-0.5) ; };

That's not valid syntax. The right-hand side of an assignment must be an expression and not a statement.

A simple solution is to turn round from a macro to an actual function. An even simpler solution is to realize that int values (a[i] is an int) doesn't have fractions, so there's nothing to round.

If you want to use floating-point values though, the correct solution is to use the standard round function, not to make up your own.

Upvotes: 1

Sourav Ghosh
Sourav Ghosh

Reputation: 134356

You don't need the return keyword, it's not a function. Get rid of it.

Quoting C11, chapter §6.8.6.4

A return statement terminates execution of the current function and returns control to its caller. [...]

which is not the purpose of your MACRO definition. Inclusion of return keyword is unwanted and invalid syntax there.

What you probably want is a syntax like

  (N >=0)? (int)(N+0.5) : (int)(N-0.5)

or, something better

 ( (N) >=0)? (int)((N)+0.5) : (int)((N)-0.5)

without the return and maybe the trailing ; also.

Upvotes: 0

Like it was told to you in a comment, macros aren't functions. They are a token substitution mechanism. So you do not return from them as you would a function.

#define round(N) (((N) >=0)? (int)((N)+0.5) : (int)((N)-0.5))

The changes I made include:

  1. Making it an expression. This involves replacing the curly braces with parentheses. This is so you could use the macro almost anywhere you could use a function. Had I left the curly braces it would have been a compound statement.

  2. Wrapping the parameter N in parentheses as well, to make sure operator precedence doesn't come back and bite us.

Upvotes: 1

Related Questions