Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

& operator cannot be applied to constants in C [duplicate]

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?

like image 970
Aquarius_Girl Avatar asked Aug 31 '17 05:08

Aquarius_Girl


2 Answers

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.

like image 59
msc Avatar answered Oct 03 '22 18:10

msc


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);
like image 34
ad absurdum Avatar answered Oct 03 '22 18:10

ad absurdum