Speaking of string literals, the C99 standard says (6.4.5.6):
It is unspecified whether these arrays are distinct provided their elements have the appropr
In the standard, equality is discussed in §6.5.9 “Equality operators”, &
is discussed in §6.5.3.2 “Address and indirection operators”, and const
is discussed in §6.7.3 “Type qualifiers”. The relevant passage about pointer equality is §6.5.9.6:
Two pointers compare equal if and only if both are null pointers, both are pointers to the same object (including a pointer to an object and a subobject at its beginning) or function, [or pointers past the end of an array]
The only definition of &
is that “The unary &
operator yields the address of its operand. […] The result is a pointer to the object or function designated by its operand.” (§6.5.3.2.3). There is unfortunately no formal definition of the word “address”; but distinct objects (for the equality defined by ==
) have distinct addresses, because the addresses are pointers that are distinct by the definition of equality above.
As for the meaning of const
, §6.7.3 doesn't indicate that const
has any bearing on what makes an object (which is “a region of data storage in the execution environment, the contents of which can represent values” by §3.14). A footnote further indicates that “the implementation need not allocate storage for such an object if its address is never used”. Although this is non-normative, it is a strong indication that if the address is used then storage must be allocated for each object.
Note that if the objects are const volatile
, then it is fairly clear (as clear as volatile
can ever be) that they can't have the same address, because const volatile
objects are mutable by the implementation. (§6.7.3.10 has an example of use of const volatile
.)
Even in the non-volatile case, const
only indicates that this part of the program is not allowed to modify the object, not that the object is read-only in general. To merge the storage of a const
object with something else, the audacious implementer would have to guarantee that nothing can modify the object. This is fairly difficult for an object with external linkage in an implementation with separate compilation (but of course we're getting away from the standard and into the won't-happen-in-practice territory).
If this is about writing a C program, then you can increase your chances by giving the objects different values:
const int x = __LINE__;
const int y = __LINE__;
If this is about a theoretical model of C, I'd go for making the objects distinct. You'll have to justify this choice by summarizing the answers here in a paragraph in (the extended version of) your paper.
On the other hand, if this is about writing an optimizing compiler, I doubt it would hurt many real-world programs to merge constants. I'd go for merging in an embedded compiler, where users are used to playing it safe with edge cases and where the memory saved could be non-negligible. I'd go against merging in a hosted platform where any gain would be negligible.
(References from N1256 a.k.a. C99+TC3. I don't think the version makes a difference.)