0

Why don't we put semicolons at the end of macro definitions?

I know that the preprocessor handles these parts of the code. Is there a relation between these two? If yes, what kind?

Is it related to a difference between how the preprocessor handles things differently when compared to the compiler? If yes, what are these differences?

dbush
  • 205,898
  • 23
  • 218
  • 273

4 Answers4

6

The macro definitions are just straight-up text replacement, including if you put a semi-colon ; there. So

#define MYVAR 4;

if used thusly:

for (i=0; i<MYVAR ; i++)

would be translated to:

for (i=0; i<4; ; i++)

Which is erroneous, it would cause a syntax error. Don't be fooled by moments where it could work, or appear to work, without side-effects. For example:

int j = MYVAR;

translates to:

int j = 4;;

Which works, but is not a good way to work.

AntonH
  • 6,359
  • 2
  • 30
  • 40
1

In addition to the example given by AntonH

#define MAX(a, b) (a > b ? a : b)
int x = MAX(4, 5);

If you defined this macro with a semicolon, you could write a statement without a semicolon, which would look quite strange:

#define MAX(a, b) (a > b ? a : b);
int x = MAX(4, 5)
AntonH
  • 6,359
  • 2
  • 30
  • 40
Millie Smith
  • 4,536
  • 2
  • 24
  • 60
1

Even if we forget about preprocessor, there are lots of places in C language-proper where we don't put a ; at the end of things. In fact, one can argue that putting a ; at the end of something is more of an exception than a rule in C. Declaration ends in a ; and expression statement ends in a ; and jump statements end in a ; - that's about it. And almost everywhere when ; is needed by the language-proper, it is needed for some justifiable grammatical reasons.

What would be the reason to require ; at the end of macro definitions? I don't see any. That's probably why it isn't there.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
0

Preprocessing directives (#define, #include, #if, #ifdef, #ifndef, etc.) are not statements, so they are not terminated by semicolons; instead, they are terminated by newline characters. If you want a preprocessing directive to span several source lines, you need to escape the newline character like so:

#define FOREACH( n, arg, func )     \
  for( size_t i = 0; i < (n); i++ ) \
  {                                 \
    (func)((arg), i);               \
  }                                  

Like the others have said, macro expansion is just dumb text substitution, so if you put a semicolon at the end of a macro definition it will be part of the expansion, which is almost never what you want.

John Bode
  • 119,563
  • 19
  • 122
  • 198