tags:

views:

323

answers:

9
+2  Q: 

C Constants

If I declare a constant say

"#define MONTHS =12" in C I am aware that pre-processor directive will replace whereever MONTHS is used, but want to know if a memory is allocated to store 12??, if yes, what would be the label and what would be the datatype.

+9  A: 

The syntax is actually:

#define MONTHS 12

No = sign allowed. And no memory is allocated in the compiled code for MONTHS, and it has no data type.

anon
Well, I think it'd be allowed, but it won't do what s?he intends to do with it :-).
Joey
With the = sign, gcc at least issues a warning.
anon
@Neil, note the space after MONTHS in his question.
Johannes Schaub - litb
@litb Well spotted, but that just makes things worse, IMHO :-)
anon
+3  A: 

No memory is allocated for preprocessor symbols on their own. If you ever use it as a value somewhere it can cause relevant allocation.

For example:

char something[1024*MONTHS];// 1024*12 bytes

otherwise the constant never outlives the compilation time. And it has no datatype.

sharptooth
+2  A: 

Isn't #define - simply find n replace by the preprocessor before it hits the compilation stage.. It replaces all instances of the symbol with the value throughout the source. Then the compiler takes over.
So don't think memory is allocated.

Gishu
+3  A: 

The whole point about the C pre-processor is that it makes it's replacements before any code is compiled. so #-defined constants aren't stored at the point they are defined, only when they are used.

Mitch Wheat
I thought the whole point was to make the maximally compilable program bigger by separating the compilation in multiple stages.
Marco van de Voort
@marco That has nothing to do with the pre-processor. Languages like Delphi, which do not have a preprocessor support separate compilation.
anon
Having a preprocessor still increases the maximal size of an compilation unit by having less symbols in the main compiler. And linking can be done in stages to keep memory down.Think very early unix systems (PDP-7 and 11 etc) here.
Marco van de Voort
+17  A: 

You most likely want your define as such:

#define MONTHS 12

/* some code here... */

int payAnnual = payMonthly * MONTHS;

To answer your question, no memory will be used. The pre-processor is unaware of such concepts as variables and memory. It is essentially an automated text editor. It will replace any occurrence of the symbol MONTHS with 12.

Since the pre-processor is so dumb, it is generally preferable to use a const variable. This gives you the benefit of type-checking, and can make compiler errors easier to read. And so long as you declare it static, the variable will be optimized away. (If you don't declare a global variable static in C, by default, it will be exported, so the compiler can't optimize it away entirely.)

static const int MONTHS = 12;
Conspicuous Compiler
If you are talking about C++, consts have local linkage and are thus not "exported".
anon
it just makes me think, C++ declaring of a constant static const int MONTHS =12 would allocate memory int size and will have 12 stored in it right? At the end of the day constant is constant and what would be that advantage in C++ having declaring const this way where memory is allocated. Was just wondering!!
Lakshmi
The C++ compiler can (and will) choose to optimise away the const, provided you do not do something like take its address. But if you want to ask about C++, you would be better off starting a nother question - C and C++ are different languages.
anon
Neil: Interesting, do you have a reference on that? I seem to recall coding for a MUD back in the day that kept a set of configuration variables as consts in a small object file so it was fast to recompile with small changes to those. It's possible they were all declared <code>extern</code>, however.
Conspicuous Compiler
It's part of the C++ Standard, section 3.5.
anon
@Lakshmi: The potential value of consts that are exported as symbols (and hence take up memory) is that they allow libraries to expose variables whose value might change. For instance, a best guess magic value for calculation of an inverse square root: http://betterexplained.com/articles/understanding-quakes-fast-inverse-square-root/
Conspicuous Compiler
It's called PREprocessor - when you click the `Compile` button, it goes through your source *before compiling*, and replaces all occurrences of MONTHS with 12. Having a constant in C++ means that you want to expose Months as a public variable, so that other users can access it and use it when you give them your library. Preprocessor defines are something meaningful only for *your* source code.
Groo
@Neil: Thanks for the info. It would be helpful to have a URL to the standard, but I'm guessing it's not a free document. After searching a bit, it appears const is a C keyword, and behaves as I had described (in C) so I revised my comment above to reflect that. My bad. That's what I get for hardly ever using pure C.
Conspicuous Compiler
@conspicuouscompiler Thanks conspicuouscompiler
Lakshmi
+2  A: 

They are used just like an actual integer, and the normal literal type for an integer is used in calculations where the macro name appears in the program.

Just as if you were to declare

#define FOO "bar"

Then occurences of FOO would be replaced with the typical usage of "bar" being a pointer to some location of the string constant in the program's object file mapped to memory.

There isn't really a difference.

Aiden Bell
+5  A: 

The preprocessor simply makes symbolic changes to the source code. Hence the code would behave the same as if you had simply replaced all occurrences of MONTHS with 12 yourself. And consequently there is no memory impact in using it.

The use of pre compiler definitions is a great way of raising the level of abstraction of your code without memory of performance impact.

Regards

Howard May
A: 

No,

weeks = 12 * 4;

Is exactly the same as:

weeks = MONTHS * 4;

Does 12 take memory? No, Therefore neither does MONTHS.

felipec
A: 

if 12 is allocated depends of the usage and got nothing to do with the preprocessor at all

Somefunction(MONTH);

would expand to

Somefunction(12);

12 here must ofc be stored somewhere, in this case it will be staticaly stored in the executable. The type will likely depend on what Somefunction take as an argument (or whatever the compiler decides fits best for this usage). There is no know label to '12'.

The preprocessoring is done before the actual compilation, as someone already wrote, it is like a automated texteditor. So the compilation stage is fully unaware of what the preprocessor did.

Joakim Elofsson