According to The C programming language by Kernighan and Ritchie, page 94
& operator cannot be applied to constants
const int u = 9;
printf ("\nHello World! %u ", &u);
So, why does that work?
You are misunderstanding between constant
and const
. Both are different things in C language.
& operator cannot be applied to constants
In C programming, It means you cannot use &(address operator)
on the literal constant to get the address of the literal constant.
For examples :
&10
or
&('a')
If you use &
operator over literal constant, the compiler will give an error because constant entity does not have corresponding address.
According to the Draft Standard §6.5.3.2 ¶1, use of the address operator must obey the following constraint:
The operand of the unary & operator shall be either a function designator, the result of a [] or unary * operator, or an lvalue that designates an object that is not a bit-field and is not declared with the register storage-class specifier.
The meaning of lvalue is given in §6.3.2.1 ¶1:
An lvalue is an expression (with an object type other than void) that potentially designates an object.
According to §3.15 ¶1 an object is a:
region of data storage in the execution environment, the contents of which can represent values.
Now, a constant is not an lvalue; a constant has a value, but a constant does not indicate an object, and a value can't be assigned to a constant.
So, a constant is not a function designator, is not the result of a []
or unary *
operator, and is not an lvalue, which means that taking the address of a constant is a constraint violation. A diagnostic message must be issued by a conforming implementation.
On the other hand, given const int u = 9;
, u
is a const
qualified variable of type int
. This declaration does reserve storage for the variable, and u
is an lvalue. The use of const
does not indicate that u
is a constant, but that the object indicated by the identifier u
is const
(which is not the same thing). It may be better to think of const
qualified variables as "read-only"; this is a promise made by the program that the object indicated by u
will not be modified. Since u
is an lvalue here (that is not a bit-field, and is not declared with the register
keyword), it is fine to take its address with &u
.
Do note that the posted code has undefined behavior, since the correct printf()
conversion specifier for printing addresses is %p
; its argument must be cast to (void *)
. Mismatched conversion specifiers and arguments lead to undefined behavior. So, the correct code would be:
const int u = 9;
printf ("\nHello World! %p ", (void *) &u);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With