Are the literal and constant the same concept in C? Is there any difference between them in usage?
3 Answers
Literals and constants are significantly different things in C. It can be said that the term literal in C stands for unnamed object that occupies memory (literals are typically lvalues), while the term constant stands for (possibly named) value that does not necessarily occupy memory (constants are rvalues).
"Classic" C (C89/90) had only one kind of literal: string literal. There were no other kinds of literals in that C. C99 additionally introduced so called compound literals.
Meanwhile, the term constant refers to explicit values, like 1
, 2.5f
, 0xA
and 's'
. Additionally, enum members are also recognized as constants in C.
Again, since literals in C are lvalues, you can take and use their addresses
const char *s = "Hello";
char (*p)[6] = &"World";
int (*a)[4] = &(int []) { 1, 2, 3, 4 };
Since constants are rvalues, you can't take their addresses.
Objects declared with const
keyword are not considered constants in C terminology. They cannot be used where constant values are required (like case labels, bit-field widths or global,static variable initialization).
P.S. Note that the relevant terminology in C is quite different from that of C++. In C++ the term literal actually covers most of what is known in C as constants. And in C++ const
objects can form constant expressions. People are sometimes trying to impose C++ terminology onto C, which often leads to confusion.
(See also Shall I prefer constants over defines?)

- 1
- 1

- 312,472
- 42
- 525
- 765
-
I wonder who misunderstood the OP, whether (s) meant "constants" as the term is used in the standard, or `const`-qualified variables. But I'd disagree that constants and literals are entirely different things, I see some similarity between `"String literal!"` and `'c'`. – Daniel Fischer Jul 31 '12 at 04:19
-
@Daniel Fischer: The OP asked about *concepts in C*. So I used the formally defined terms from the language specification. A const-qualified variable is not a constant in C. And the question is about constants. And no, there's no relevant similarities between string literal and character constant. It is no different that saying that a horse is similar to a table just because both have four legs. True, but irrelevant. – AnT stands with Russia Jul 31 '12 at 04:24
-
I know that a const-qualified variable is not a constant. I just wonder whether the OP does. The other answers interpreted it as const-qualified variable, so why should the OP not do the same? As for _no_ relevant similarities, I guess that's a matter of interpretation. Literals can appear in initialisers for static variables, where otherwise only constants can appear. It's not much, but enough to make me say that entirely/completely different may be an overstatement. – Daniel Fischer Jul 31 '12 at 04:38
-
@Daniel Fischer: Well, the terms *literal* and *constant* are very strictly defined terms in C language. I see no reason to jump to the conclusion that the OP misused these terms before the OP gives us any indication of that. And even if the OP misused these terms, helping the OP to use them properly is the right thing to do. There's no need to bring over "interpretations" without a slightest reason to do so. Literals and constants are indeed completely different things in C: the latter are objects (lvalues) and the former are values (rvalues). That's a huge difference. – AnT stands with Russia Jul 31 '12 at 04:45
-
Well, I don't know whether the OP misused the terms, and I suspend judgment on that. But the terms are misused often enough to consider the possibility. I hope we can agree on that;) (And yes, they're very different beasts, just IMO not _completely_, YMMV.) – Daniel Fischer Jul 31 '12 at 04:57
-
Oh, and the interpretation was about the meaning of completely, not the meaning of constant and literal. It just occurred to me that you may have thought that. – Daniel Fischer Jul 31 '12 at 04:58
-
Replaced with "significantly" :) – AnT stands with Russia Jul 31 '12 at 04:59
-
@AndreyT I found the terms in C programming language: A string constant, or string literal, is a sequence of zero or more characters surrounded by double quotes. From this statement I got that string constant and string literal are the same concept for the same thing, isn't it? – Victor S Jul 31 '12 at 05:37
-
@Victor S: Not exactly. There no such thing as "string constant" in formal C terminology. Sequence of characters in double quotes is a *string literal* and *string literal* only. Where did you find a reference to "string constant"? – AnT stands with Russia Jul 31 '12 at 05:41
-
I also found that the constant always be used with character and literal always be used with string in C99, so called a character constant, a string literal rather than character literal and string constant, is this a convention? – Victor S Jul 31 '12 at 05:46
-
@AndreyT In
p54: A string constant, or string literal, is a sequence of zero or more characters surrounded by double quotes, as in "I am a string" – Victor S Jul 31 '12 at 05:50 -
@Victor S: The K&R is apparently being informal. The formal C terminology does not allow for "string constants". "Character constant" and "string literal" follow from the definition of "constant" and "literal" in language specification. So in that sense it is more than a "convention". – AnT stands with Russia Jul 31 '12 at 07:04
-
Several major mistakes here. Literals are rvalues. They can *never* be lvalues. 0,1,2 etc are all literals, as are 0.0, 0f, etc. – user207421 Aug 01 '12 at 00:15
-
@EJP: Absolutely incorrect. As I said above, you are making the popular major mistake of forcing irrelevant C++ terminology into the domain of C language. In reality in C language `1`, `0.0` etc. are **not** *literals*, but *constants*. And, again, in C language all literals are *always* lvalues, as I said above. – AnT stands with Russia Aug 01 '12 at 00:28
The C standard (specifically ISO/IEC 9899, Second edition, 1999-12-01) does not define “literal” by itself, so this is not a specific concept for C. I find three uses of “literal”, described below.
First, a string literal (or “string-literal” in the formal grammar) is a sequence of characters inside quotation marks, optionally prefixed with an “L” (which makes it a wide string literal). This is undoubtedly called a literal because each character in the string stands for itself: A ”b” in the source text results in a “b” in the string. (In contrast the characters “34” in the source text as a number, not a string, result in the value 34 in the program, not in the characters “3” and “4”.) The semantics of these literals are defined in paragraphs 4 and 5 of 6.4.5. Essentially, adjacent literals are concatened ("abc" "def"
is made into "abcdef"
), a zero byte is appended, and the result is used to initialize an array of static storage duration. So a string literal results in an object.
Second, a compound literal is a more complicated construct used to create values for structures. “Compound literal” is an unfortunate name, because it is not a literal at all. That is, the characters in the source text of the literal do not necessarily stand for exactly themselves. In fact, a compound literal is not even a constant. A compound literal can contain expressions that are evaluated at run-time, including function calls!
Third, in 6.1 paragraph 1, the standard indicates that “literal words and character set members” are indicated by bold type. This use of “literal” is describing the standard itself rather than describing things within the C language; it means that “goto” in the standard means the string “goto” in the C language.
Aside from string literals, I do not think “literal” is a particular concept in C.
”Constant”, however, is a significant concept.
First, there are simple constants, such as “34”, “4.5f”, and “'b'”. The latter is a character constant; although written with a character, it has an integer value. Constants include integer constants (in decimal, octal, and hexadecimal), floating constants (in decimal and hexadecimal), character constants, and enumeration constants. Enumeration constants are names specified in “enum” constructs.
Second, there are constant expressions, defined in 6.6. A constant expression can be evaluated during translation (compile time) rather than run time and may be used any place that a constant may be. 6.6 sets certain rules for constant expressions. As an example, if x
is a static array, as declared by static int x[8];
, then &x[(int) (6.8 * .5)]
is a constant expression: It is the address of element 3 of x. (You would rarely using floating-point to index arrays, but I include it in the example to show it is allowed as part of a constant expression.)
Regarding “const”: The standard does not appear to specifically define a const-qualified object as constant. Rather, it says that attempting to modify an object defined with a const-qualified type through an lvalue (such as a dereferenced pointer) with non-const-qualified type, the behavior is undefined. This implies a C implementation is not required to enforce the constantness of const objects. (Also, note that having a pointer-to-const does not imply the pointed-to object is const, just that the dereferenced pointer is not a modifiable lvalue. There could be a separate pointer to the same object that is not const-qualified. For example, in int i; int *p = &i; const int *q = p;
, q is a pointer-to-const-int, but i is not a const object, and p is a pointer to the same int although it is pointer-to-int, without const.)

- 195,579
- 13
- 168
- 312
-
`6.8 * .5` is `3.4`, where is the decimal part `0.4`, is it truncated? – Kindred Nov 21 '18 at 17:52
-
1@ptr_user7813604: Actually array subscripts must be integers, so I should have included a cast in the example: `&x[(int) (6.8 * .5)]`. Yes, when converting floating-point to integer, the fractional part is discarded. – Eric Postpischil Nov 21 '18 at 18:04
Not quite. Constant variables (as opposed to constants defined in macros) are actual variables with dedicated storage space, so you can take the address of them. You can't take the address of a literal.
Edit: Sorry everyone, it appears that I was mistaken.

- 37,781
- 10
- 100
- 107
-
1Additional note: The storage space of `static const` variables can be completely elided by the compiler, so you do not actually pay a "penalty" for using constant variables. – Dietrich Epp Jul 31 '12 at 04:06
-
3"You can't take the address of a literal". That's absolutely incorrect. You *can* take address of a literal. String literal actually decays to its own address, for one example. And you can explicitly take address of a compound literal. Actually in C *literal* (as opposed to constant) is what you *can* take address of. You can't take address of a constant. – AnT stands with Russia Jul 31 '12 at 04:22
-
And to add onto what @AndreyT says, you can't take the address of all `const`-qualified variables, either, namely when you declare them with storage class `register`. – Jens Gustedt Jul 31 '12 at 10:00