0

I don't see the need of using macro to define something , say in below example:

#define TELEPHONE 443 //why use this

int telephone = 443; //when same job is done by a regular variable

why would any one use macro for defining (declaring variable in C language) ? as in above scenario?

David Prun
  • 8,203
  • 16
  • 60
  • 86
  • Closely related: ["static const" vs. #define in C](http://stackoverflow.com/q/1674032), [Why would someone use #define to define constants?](http://stackoverflow.com/q/6274008), [Shall I prefer constants over defines?](http://stackoverflow.com/q/2308194) – jscs Sep 22 '13 at 03:32
  • Changing the variable value to "443" , just not to confuse experts who are trying to help me understand the usage of Macro. thanks – David Prun Sep 22 '13 at 03:33
  • @JoshCaswell: It is not just "related", it is the exact duplicate. – LihO Sep 22 '13 at 03:34
  • @LiHO: which of the three that Josh cited (and the one that I cited) is 'the exact duplicate'? They could all be to some extent. Maybe they even need merging (or just cross-linking). The '`static const` vs `#define`' question discusses different techniques for creating 'symbolic constants'; this question is more closely about 'why should I use symbolic constants at all'. – Jonathan Leffler Sep 22 '13 at 03:38

4 Answers4

1

Why would any one use macro for defining (declaring variable in C language) ?

The macro does not define a variable, it defines a constant. Your C program that uses TELEPHONE that's #defined is indistinguishable to the compiler from a program that contains the hard-coded value 443.

Unlike int telephone variable, the TELEPHONE macro cannot be changed at run-time, and does not have an address.

Finally, it is possible to provide values for macros on the command line when calling the compiler - something impossible to do when you are dealing with C variables. Instead of defining #define TELEPHONE 443 you could pass the value on the command line, like this:

gcc -DTELEPHONE=443 myprog.c
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Changing the variable value to "443" , just not to confuse experts who are trying to help me understand the usage of Macro. thanks – David Prun Sep 22 '13 at 03:33
1

Using a variable takes up space in the final image, which may not be required or desired (e.g. in embedded applications), whereas a define is handled strictly by the compiler (preprocessor).

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
1

There are several cases when a macro is more appropriate. The top of my head are:

1.To define a constant:

#define PI 3.1415926

2.To use as a constant expression.

#define BUFSIZE 1024

later you can use

int buffer[BUFSIZE];

This job cannot be done even if you use const int bufsize = 1024; (without using variable length array)


EDIT:

To clarify the use of const from the comment, in this code:

int main()
{
    const int x = 5;
    int array[x]; 
    return 0;
}

array is actually a variable length array, compile it with gcc test.c -std=c89 -pedantic, will generate the warning:

warning: ISO C90 forbids variable-size array `array'

The problem is, const variable in C isn't a constant expression, this is exactly my point of using #define in this situation. And this is one of the differences between C and C++.

Reference: C FAQ

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
  • 4
    Not true! This is legal C {const int x = 5; int array[x]; } – Mike Makuch Sep 22 '13 at 03:57
  • I thought there was some situation where that wouldn't work like if you have the constant defined in some other file and have made if globally visible by declaring it extern in the header, but I tried it out and it works! Is it because I am using a newer compiler now and in the past it didn't work? I thought it may be an issue because the value of x is not know for the array size until the linker stage. – Nathan Day Sep 22 '13 at 04:08
  • @koodawg Sure that's legal C, but that's a **variable length array**, not a normal array. Use C89 mode to compile it and see the warning. – Yu Hao Sep 22 '13 at 04:32
  • @NathanDay See my edited part, I didn't say it's illegal, I said it's not a fixed-sized array as people may assume so, it's actually a C99 variable length array. It's nice that you tried it out, config your compiler in C89 mode and it won't compile. – Yu Hao Sep 22 '13 at 04:56
  • 2
    @koodawg: This is legal only in local scope because of VLA feature of C99. Try this `struct S { int array[x]; };` and see what happens. Also, try `int array[x];` in file scope. Or try `static int array[x];` anywhere. None of these will work with `const int x`. – AnT stands with Russia Sep 22 '13 at 05:10
  • Gotcha, no good in pre C99. But it is good C99! – Mike Makuch Sep 22 '13 at 05:18
  • 1
    @koodawg The point is, it's not fixed size array, as some would assume so. And variable length arrays do have some limitations. That's why I think using `#define` has some advantages in this situation. AndreyT's comment has some very good point. – Yu Hao Sep 22 '13 at 05:24
1

dasblinkenlight pretty much covers it but I would just clarify some things they say, macros don't really define constants, you do that with the const modifier, and you should be using that most of the time. A macro defines substitution text, the only thing it knows about the language you are writing in is its use of spaces. So for macros you can do stuff like this

#define CODE_SNIPPET 10; i++ ) printf( "Hello %d\n"

for( int i = 0; i < CODE_SNIPPET , i );

which before being passed to the parser would be convert by the preprocessor to

for( int i = 0; i < 10; i++ ) printf( "Hello %d\n" , i );

Which is very powerful, but obviously open for abuse. I very rarely if ever use macros for constants, instead I will define the values as const in a .c file and then declare it extern in the header like

const int kAnswerToEveryThing = 42;    // .c file

extern const int kAnswerToEveryThing;        // .h file

I have one project that I use macros quite a bit, this is in Objective-C not c, but the macro system is identical and I have defined macros that expand out into class methods which add meta data to a class to be used by my library, its to do the same functionality as Java's annotations.

Nathan Day
  • 5,981
  • 2
  • 24
  • 40