31

I've just been going back over a bit of C studying using Ivor Horton's Beginning C book. I got to the bit about declaring constants which seems to get mixed up with variables in the same sentence.

Just to clarify, what is the difference in specifying constants and variables in C, and really, when do you need to use a constant instead of a variable? I know folks say to use a constant when the information doesn't change during program execution but I can't really think of a time when a variable couldn't be used instead.

skaffman
  • 381,978
  • 94
  • 789
  • 754
Adam N
  • 319
  • 1
  • 3
  • 3
  • Fixed length saves memory where worst case copying to new array works – Niklas R. Jun 01 '10 at 22:15
  • This question requires only one counter-example: why would you make PI a variable? – Hans Passant Jun 01 '10 at 22:30
  • @Hans Passant: Are you sure Pi is a constant? So far it's only been measured in the proximity of Earth. Are you sure it's constant throughout the space-time continuum? –  Jun 01 '10 at 22:35
  • Agreed, a value of "3" is not unlikely close to the horizon of a black hole. Which requires a redefinition of the bool type too, have to add "file irretrievably lost". – Hans Passant Jun 01 '10 at 22:45
  • 3
    @Developer Art: Pi is an abstract mathematical constant independent of physical space, as is every other mathematical constant. – David R Tribble Jun 02 '10 at 00:13
  • To be technically pedantic, you're asking about *variables* versus *constant variables* (yes, that is an oxymoron). A true *constant* is a literal, typically written as a preprocessor macro. – David R Tribble Jun 02 '10 at 00:16
  • Let's get more pedantic, the C language specification talks about objects, constants and literals. – Thomas Matthews Jun 02 '10 at 00:39
  • @Loadmaster: That would imply that physical properties of the universe do not change with time or position. With all due respect, you can't be completely sure of that. Anomalies and paradoxes may exist. The mankind has only seen its very small corner of the universe. Not to mention parallel dimensions and other things. –  Jun 02 '10 at 07:44
  • @Developer Art: As an abstract mathematical value, pi has nothing whatsoever to do with the physical universe. The fact that pi is a constant in no way implies anything about the Universe changing or not. – David R Tribble Jun 14 '10 at 20:30

10 Answers10

38

A variable, as you can guess from the name, varies over time. If it doesn't vary, there is "no loss". When you tell the compiler that the value will not change, the compiler can do a whole bunch of optimizations, like directly inlining the value and never allocating any space for the constant on the stack.

However, you cannot always count on your compiler to be smart enough to be able to correctly determine if a value will change once set. In any situation where the compiler is incapable of determining this with 100% confidence, the compiler will err on the side of safety and assume it could change. This can result in various performance impacts like avoiding inlining, not optimizing certain loops, creating object code that is not as parallelism-friendly.

Because of this, and since readability is also important, you should strive to use an explicit constant whenever possible and leave variables for things that can actually change.

As to why constants are used instead of literal numbers:

1) It makes code more readable. Everyone knows what 3.14 is (hopefully), not everyone knows that 3.07 is the income tax rate in PA. This is an example of domain-specific knowledge, and not everyone maintaining your code in the future (e.g., a tax software) will know it.

2) It saves work when you make a change. Going and changing every 3.07 to 3.18 if the tax rate changes in the future will be annoying. You always want to minimize changes and ideally make a single change. The more concurrent changes you have to make, the higher the risk that you will forget something, leading to errors.

3) You avoid risky errors. Imagine that there were two states with an income tax rate of 3.05, and then one of them changes to 3.18 while the other stays at 3.07. By just going and replacing, you could end up with severe errors. Of course, many integer or string constant values are more common than "3.07". For example, the number 7 could represent the number of days in the week, and something else. In large programs, it is very difficult to determine what each literal value means.

4) In the case of string text, it is common to use symbolic names for strings to allow the string pools to change quickly in the case of supporting multiple languages.

Note that in addition to variables and "constant variables", there are also some languages with enumerations. An enumeration actually allows you to defines a type for a small group of constants (e.g., return values), so using them will provide type safety.

For example, if I have an enumeration for the days of the weeks and for the months, I will be warned if I assign a month into a day. If I just use integer constants, there will be no warning when day 3 is assigned to month 3. You always want type safety, and it improves readability. Enumerations are also better for defining order. Imagine that you have constants for the days of the week, and now you want your week to start on Monday rather than Sunday.

Uri
  • 84,589
  • 46
  • 214
  • 312
  • 5
    OP isn't asking about literals. the question was WHY BOTHER using constants when things don't change...why NOT just use variables for everything? it's not like we're going to run out... – Brian Postow Jun 01 '10 at 22:00
  • 3
    I feel the first paragraph of my response answers that: no need to use a variable if it doesn't change over time. But I will clarify this further. – Uri Jun 01 '10 at 22:02
  • I would also add: 5) Type safety. – matias Jun 01 '10 at 22:03
  • Nah, I agree with Brian, too much information, totally. But there again, what will the title lead people here, expecting? – James Morris Jun 02 '10 at 00:43
  • Thanks everybody who replied to this, hope I haven't opened a can of worms. I think i got a little lazy in my programming and did end up using variables in most cases. Now returning to C after spending a long time in Python (never used constants there either) it's good to understand why we do things the way we do. Brushing up on specifying my constants now. Thanks again. – Adam N Jun 02 '10 at 16:31
  • 1
    `3.14` is obviously `((e*phi)^(phi/2)-3) << 1` – Mateen Ulhaq Oct 20 '11 at 05:21
18

Using constants is more a way of defensive programming, to protect yourself from yourself, from accidentally changing the value somewhere in the code when you're coding at 2 a.m. or before having drunk your coffee.

Technically, yes, you can use a variable instead.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
  • 3
    @wallacoloo: Of course, thank you. That's what happens when writing an answer at 12am. :) –  Jun 01 '10 at 22:04
  • 7
    Don't forget, *sleep* is also a defensive programming tactic. – Jackson Sep 18 '16 at 18:19
  • You mean like this? ;) startBackgroundProcess(); sleep(1000); // Ensure the process finished starting useBackgroundProcesses(); – duckbrain Jul 31 '17 at 19:51
13

Constants have several advantages over variables.

Constants provide some level of guarantee that code can't change the underlying value. This is not of much importance for a smaller project, but matters on a larger project with multiple components written by multiple authors.

Constants also provide a strong hint to the compiler for optimization. Since the compiler knows the value can't change, it doesn't need to load the value from memory and can optimize the code to work for only the exact value of the constant (for instance, the compiler can use shifts for multiplication/division if the const is a power of 2.)

Constants are also inherently static - you can declare the constant and its value in a header file, and not have to worry about defining it exactly one place.

Michael
  • 51,314
  • 5
  • 111
  • 139
  • 2
    Such a guarantee can make later debugging and maintenance much easier - if something is a variable, you'll often find yourself searching for any places in the code that changes it; if it's a constant, you can avoid that. – caf Jun 01 '10 at 23:32
10

For one, performance optimization.

More importantly, this is for human readers. Remember that your target audience is not only the compiler. It helps to express yourself in code, and avoid comments.

const int spaceTimeDimensions = 4;

if(gpsSattelitesAvailable >= spaceTimeDimensions)
  Good();
Pavel Radzivilovsky
  • 17,994
  • 3
  • 54
  • 65
3

For a low-level language like C, constants allow for several compilation optimizations.

For a programming language in general, you don't really need them. High level dynamic languages such as Ruby and JavaScript doesn't have them (or at least not in a true constant sense). Variables are used instead, just like you suggested.

Jakob
  • 23,205
  • 7
  • 44
  • 55
2

The const keyword is often used for function parameters, particularly pointers, to suggest the memory the pointer points to will not be modified by the function. Look at the decleration for strcpy for instance:

char *strcpy(char *dest, const char *src);

Otherwise, for example, an declaration such as

const int my_magic_no = 54321;

might be preferred over:

#define MY_MAGIC_NO 54321

for type safety reasons.

James Morris
  • 4,651
  • 3
  • 27
  • 49
2

Constant is when you just want to share the memory, and it doesn't change.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
1

It's a really easy way to trap a certain class of errors. If you declare a variable const, and accidentally try to modify it, the compiler will call you on it.

crazyscot
  • 11,301
  • 2
  • 36
  • 39
1

Constants are very necessary in regards to declaration and intialization of variable for any purpose such as at the starting of the loop, to check the condition within the if -else statement, etc.

For more reference, feel free to read either of the following articles:

Nightfirecat
  • 10,836
  • 6
  • 32
  • 50
yogi
  • 11
  • 1
0

Not using const can mean someone in a team project could declare where int FORTY_TWO = 42 and make it equal FORTY_TWO = 41 somewhere else by another team member. Therefore the end of the world happens and you also loose the answer to life. with const although none of this will ever happen. Plus const is stored elsewhere in memory, when compared to the storage of normal variables, and is more efficient.