1

I am learning C programming, and my book says that unlike variables, constants cannot be changed during the program's execution. And that their are two types of constants Literal and Symbolic. I think that I understand Symbolic pretty well. But Literal Constants are confusing me. The example it gave me for was

int count = 20;

I wrote this simple program, and I could change the value of the Literal Constant.

/* Demonstrates variables and constants */
#include <stdio.h>

/* Trying to figure out if literal constants are any different from variables */
int testing = 22;


int main( void )
{
    /* Print testing before changing the value */
    printf("\nYour int testing has a value of %d", testing);

    /* Try to change the value of testing */
    testing = 212345;

    /* Print testing after changing the value */
    printf("\nYour int testing has a value of %d", testing);

    return 0;
}

It outputted this:

  Your int testing has a value of 22
  Your int testing has a value of 212345
  RUN SUCCESSFUL (total time: 32ms)

Can someone explain how this happens, am I declaring it wrong? Or is there any difference between normal variable and literal constants?

-Thanks

Dropoff510
  • 51
  • 2
  • 7

3 Answers3

3

The literal constant is the 20. You can change the value of count, but you cannot change the value of 20 to be, for example, 19.

(As some trivia, there are versions of FORTRAN where you could do exactly this, so it's not meaningless to talk about)

Patashu
  • 21,443
  • 3
  • 45
  • 53
  • 1
    Fun fact: you can do this in Java with reflection. (like FORTRAN, except not many people use FORTRAN) – Ryan Amos Feb 25 '13 at 04:50
  • @Ryan Amos Woah, you can do it in Java too? The things you learn :) – Patashu Feb 25 '13 at 04:51
  • http://stackoverflow.com/questions/3301635/change-private-static-final-field-using-java-reflection – Ryan Amos Feb 25 '13 at 04:52
  • Yes, I recall an old FORTRAN program with a recalcitrant bug. Finally traced it down to the statement `1 = 2`, which was intended to have been `I = 2`. – Hot Licks Feb 25 '13 at 04:54
  • @RyanAmos - I don't know of any way you could change the literal `1` in Java, with or without reflection. – Hot Licks Feb 25 '13 at 04:56
  • @HotLicks It will only work for booleans and strings, I think. – Ryan Amos Feb 25 '13 at 17:30
  • @RyanAmos - Booleans and other "scalars" are immediates in the bytecode (and in any generated machine code) can cannot be changed. Strings are in the class file as string literals -- you could perhaps (with the proper interface) change them after loading (since they translate to interned strings) but I don't see how reflection would do it. – Hot Licks Feb 25 '13 at 18:36
  • @HotLicks As that answer explained, boolean literals are references to Boolean.TRUE/FALSE. If you were to say `boolean a = 1 == 1`, this would not be affected. Interned strings (including string literals) would be affected by using reflection to change their values. Because all strings of that value that are interned point to that specific location, all of those strings would be affected. – Ryan Amos Feb 25 '13 at 22:03
  • @RyanAmos - I seriously doubt that reflection will allow you to change the value of an interned string. Doing so would instantly break many parts of the JVM -- hash tables wouldn't work, even the intern table itself would break, etc. In fact, changing the value of ANY string is a no-no. You could do it with low-level JNI, of course, but all bets are off is you do that. – Hot Licks Feb 25 '13 at 22:28
  • @HotLicks Yeah, you're right. It will mess things up, but you can still do it. http://stackoverflow.com/questions/6932772/effect-of-changing-string-using-reflection – Ryan Amos Feb 25 '13 at 22:30
  • I still find it hard to believe. In any event, it should not be done -- I know the internals of JVMs pretty well and I wouldn't do it in anything even remotely "production". – Hot Licks Feb 25 '13 at 22:32
0

The literal in this case is the number 22 (and later the number 212345). You assign this literal to a variable testing. This variable can be changed.

This is a little trickier when it comes to strings and string literals. If you have a pointer to a string literal, you can change the actual pointer to point to some other string, but you can change what the original pointer points to.

For example:

const char *string_pointer = "Foobar";

With the above definition, you can not do e.g. string_pointer[0] = 'L';, as that is an attempt to modify the literal string that the pointer points to.


Depending on context, a symbolic constant can be either a "variable" declared as const or a preprocessor macro.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • But with some C implementations you can cast the pointer to a non-const version and modify the literal "Foobar" -- a few programs did this semi-intentionally in the olden days (before "const" was even a keyword). In most current C implementations, though, the literal will be in write-protected storage, and attempting to modify it will result in a trap. – Hot Licks Feb 25 '13 at 04:59
  • @HotLicks Modifying a string literal (e.g. by casting away the `const`) is undefined behavior. It _might_ result in a trap, it _might_ work, or it _might_ do something completely different. – Some programmer dude Feb 25 '13 at 06:17
  • When I started with C it was *all* "undefined behavior" -- the only "standard" was K&R, which just enough to describe the basic language. – Hot Licks Feb 25 '13 at 11:58
0

A literal constant in C is just any number itself, e.g. your 20. You cannot change it by doing, say, 20 = 50;. That is illegal.

There are also constant variables, e.g. const int blah = 42;. You cannot change this blah by doing something like blah = 100;.

But if you have a normal, non-constant variable, e.g. int foo = 123;, you can change it, e.g. foo = 456;.

Alexey Frunze
  • 61,140
  • 12
  • 83
  • 180