1

Certainly a dup and I shall remove it ASAP I'll run into an answer. I just can't find what I'm looking for.

What does this two lines in c mean?

#define NN_DIGITS     (  4)
#define MM_MARKS_DONE (255)

I know what #define and #define () does, where #define () execute the macro in (), but I don't know this particular caveat (with an integer).

Is actually redundant to write down () to define an integer value? Shall this values be interpreted bitwise? What will happen if we shan't write (). Will 4 and 255 be taken as a string?

SNR
  • 712
  • 1
  • 8
  • 22

2 Answers2

5

Keyword: "execute". This is the root of your misunderstanding.

Macros aren't executed. They are substituted. The preprcosseor replaces the token NN_DIGITS by the token sequence ( 4). As a matter of fact, it would replace it with practically any token sequence. Even #define NN_DIGITS ( %34 (DDd ] is a valid macro definition (courtesy of my cat), despite the fact we most certainly don't want to try and expand it.

Is actually redundant to write down () to define an integer value?

From a practical standpoint, yes, it's redundant. But some would probably do it to maintain consistency with other macros where the resulting expressions can depend on the presence of parenthesis.

Shall this values be interpreted bitwise?

Everything is bitwise to a computer.

What will happen if we shan't write (). Will 4 and 255 be taken as a string?

No, it will just be the tokens 4 and 255 as opposed to the sequences ( 4) and (255) respectfully. The preprocessor deals only in tokens, it knows practically nothing about the type system. If the macro appear in a program, say:

int a = NN_DIGITS;

It will be turned by the preprocessor into:

int a = (  4);

And then compiled further by the other steps in the pipeline of turning a program into an executable.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
  • Terrific. "Macros are not executed but substituted". Thanks a lot for your time! – SNR Jun 16 '21 at 10:13
  • 2
    there's a case where defining `(4)` instead of `4` will make a difference: [Is there a good reason for always enclosing a define in parentheses in C?](https://stackoverflow.com/q/9081479/995714) – phuclv Jun 16 '21 at 10:17
  • 1
    @phuclv - That is highly irrelevant to the level I aimed this answer to be. Mentioning concatenation sorcery when explaining the simple fact macros are substituted will serve primarily to obfuscate. – StoryTeller - Unslander Monica Jun 16 '21 at 10:19
  • @phuclv as matter of fact the use of `()` is actually a good-practice, good to know. Thanks a lot for your time! – SNR Jun 16 '21 at 10:57
  • Please update this answer with more from your cat. – Eric Postpischil Jun 16 '21 at 17:16
1

The parenthesis does absolutely nothing in this case - it's just noise.

There's a general rule of survival saying that function-like macros should always:

  1. Wrap each occurrence of a macro parameter in parenthesis, and
  2. Wrap the whole macro in an outer parenthesis

That is:

#define ADD(x,y) x + y       // BAD
#define ADD(x,y) (x) + (y)   // BAD
#define ADD(x,y) ((x) + (y)) // correct

This is to dodge issues of operator precedence and will be addressed by any decent beginner-level learning material.

Overly pedantic people who've learned the above rules tend to apply them to all macros, not just function-like macros. But in case the macro contains nothing but a single integer constant (a single pre-processor token), then the parenthesis achieves absolutely nothing.

Is actually redundant to write down () to define an integer value?

Yes, it just adds noise.

Shall this values be interpreted bitwise?

Macros are mostly just to regard as text replacement. What you do with the value in the calling code is no business of the macro.

What will happen if we shan't write ()

The code will get slightly easier to read.

Will 4 and 255 be taken as a string?

No, why would they.

There is a specific case where the parenthesis causes harm though, and that is when you use macros to convert a pre-processor constant to a string. Suppose I have this program:

#define STR(x) #x
#define AGE(x) STR(x)
#define DOG_AGE 5

int main(void)
{
  puts("My dog is " AGE(DOG_AGE) " years old.");
}

AGE expands the macro DOG_AGE to 5 and then the next macro converts it to a string. So this prints My dog is 5 years old. because the # operator converts the pre-processor token exactly as it is given. If I add "useless noise parenthesis" to the macro:

 #define DOG_AGE (5)

Then the output becomes My dog is (5) years old. Not what I intended.

Lundin
  • 195,001
  • 40
  • 254
  • 396