tags:

views:

591

answers:

10

when doing like this:

const int a = 5;

I wonder if a will get 4-byte of memory just like a variable ? (in 32 bit system)

+2  A: 

(answer removed but left the discussion in the comments)

jheddings
As stated above, what you say isn't necessarily correct
chollida
Improved verbiage to clarify optimization criteria.
jheddings
No, it is not like a `#define` at all. You can use a `#define` constant to specify array size in C89/90, but you can't do it with a `const int` object, just as one example. In C++ constants are "much like a type-safe define", but not in C. Even in C99 there are still considerable differences.
AndreyT
I'm not sure why you say that a `const int` cannot be used for an array size. Doing a simple check shows that it works fine (compiled using C89). Can you explain more?
jheddings
@jheddings: Apparently you are relying on some compiler extension, like the one in GCC, which allows variable-sized array declarations even in C89/90. Disable compiler extensions and try again. Once again, it is illegal in C89/90 to specify array size by a `const int` object.
AndreyT
@jheddings: When it comes to what's legal and what's not, "trying" is not the best way to figure out the answer. But if you want to go that way, it is always better to do it with a respected compliant compiler, like Comeau Online, for example, not with such a motley mix of rampant non-standard fantasies as GCC is in its default mode.
AndreyT
@AndreyT I'm not able to find that restriction in the ANSI C spec... According to the spec, an array is declared in the form `D[constant-expression<opt>]` and the constant-expression is "A constant expression that can be evaluated during translation rather than runtime, and accordingly may be used in any place that a constant may be." This is the same usage as in, say, a `case` label of a `switch` statement. Would that imply, then, that a `const int` cannot be used in a case label?
jheddings
@AndreyT: BTW - I'm not trying to "be right" here... Just trying to learn (and thanks for the extended discussion).
jheddings
@jheddings: Absolutely! In C languiage (both C89/90 and C99) a `const int` object cannot be used in `case` label.
AndreyT
Case labels and array sizes in C have to be Integral Constant Expressions (ICEs). The definition of ICE is given in 6.4 in C89/90 (or 6.6/6 in C99). And ICE can only include *constants*. Note, that in C language (as opposed to C++) the term *constant* means "literal value". For example, `5` is a "constant" in C, but a `const int` object is *not* a constant in C. This is a bit counterintuitive, but it is true. Once you used a `const int` object in an expression, it is no longer an ICE and, therefore, can't be used to declare array size or as a case label.
AndreyT
+1  A: 

It depends on your architecture but yes whether you make something const or not does not really affect its size but more its location in memory. Now, there are some compiler optimizations that may change what you think will actually happen but this is the basic idea.

BobbyShaftoe
+12  A: 

Yes it will. Although if you never take it's address then the optimizer might well remove it entirely and just replace any references to the constant with the number 5 in your case.

John Burton
Constant objects in C have external linkage by default. Which is why it is kinda difficult for the optimizer to remove them: they have to be exported from the object file. Only a more advanced global optimizers can do that, so don't be surprised if it is not removed. In C, if you want a "removable" constant you have to declare it `static` explicitly.
AndreyT
This means that the compiler most likely *will* replace all references to the constant with literal `5`, but still it has no immediate freedom to remove the original constant object from memory (unless it has a way to know that it is indeed never referenced anywhere in the program).
AndreyT
while removed from stack and heap it will be present in the assembly code (one or several times) if not mixed at compile time with another constant.
fa.
@Andrey: Assuming that the OP wants to declare the constant as global, adding static would reduce its scope, wouldn't it?I do not understand why static would make it removable, would you care to explain or add a link?Do you must just that: limiting the scope tells the compiler that no other module will come and fiddle with the constant. If the compiler knows all the ways in which a is used, then it can make it "removable"?
Gauthier
@Gauthier: Yes, that's exactly what I mean. Traditional C compiler works "per translation unit". It can easily analyze all references within a translation unit (and remove things that are not needed), but it can't analyze the references within the entire program (it simply can't see the entire program). When you declare a const object `static` you tell the compiler that it is restricted to a single translation unit, thus giving the compiler full freedom to remove it. A smart compiler (and linker) can eventually remove even a const object with *external* linkage, but this is more complicated.
AndreyT
A: 

It might take the usual amount, but if you only use it in ways that never require it to have an address, the compiler/linker may optimize it away so it doesn't occupy any memory at all.

Jerry Coffin
A: 

Generally the constant will take the same space as a variable, so if int is 32bit on your architecture, a will take 32bit as well. However the compiler might also decide to directly put the constant into the code, not assining space for the constant itself at all. This will depend on where the constant is actually defined, meaning if the compiler is able to determine that there is no chance to either modifiy a (e.g. through const casts) or take the address of a.

Grizzly
A: 

It depends on the compiler.

For example:

const int a = 4;

This could be handled by the compiler allocating 4 bytes and just enforcing immutability.

If you had a constant string:

static final java.lang.String name = "Foobar";

The compiler could remove the variable and replace it with the actual string "Foobar" everywhere the variable is used. This doesn't take space from the heap but it still has to be stored somewhere in the programs data segment. Java tries to do this when it finds a quoted string that is being used in multiple places, so it only has to store one copy of it.

Either way, constants don't eliminate storage allocation. At best they can only minimize the storage needed.

Kelly French
I also think it depends on the compiler
tsubasa
+2  A: 

It depends.

const int a = 5;

Will take four bytes of memory (or however many bytes an int takes up on your system).

If you make it static:

static const int a = 5;

Then the optimizer is free to replace each instance of a with the value of 5. The optimizer cannot do that in the first (non-static) case simply because you may refer to a in a separate compilation unit with:

extern const int a;
Ferruccio
A: 

On an embedded system, where read-only memory is separate from writable memory, this constant will take up no RAM, it will be stored only in ROM. Likewise, on a system with virtual memory, constants will get loaded into read-only memory pages and will only take up RAM once no matter how many running copies of the program there are.

Adam Goode
+1  A: 

There's no difference in memory consumption between int a and const int a.

Note though, that in C objects declared as const don't form constant expressions (as opposed to C++) and have external linkage by default (as opposed to C++, again). All this means that in C a constant object is pretty much the same thing as a non-constant object, just non-modifiable.

Also, it means that in C a constant object has very little chance to get "removed", as other answers claim it will. If you really want it to make it "removable" in C, you have to declare it as static explicitly. But even that won't make a const int object to form constant expressions, i.e. you still can't use it to designate array size in C89/90 and in C99 the resultant array is still a variable-length array (VLA).

AndreyT
A: 

a constant variable requires 4 bytes of memory, but if it is a value it requires 0 bytes since the assembly code will embbed the value like this

mov eax, 5

here 5 don´t comes from a variable but it is the constant 5, and it will even generate faster code since no memory call are required to retrieve the value, it is just part of the assembly code

Arabcoder