In C, are const variables guaranteed to be distinct in memory?

前端 未结 4 2177
死守一世寂寞
死守一世寂寞 2021-02-08 02:47

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

4条回答
  •  忘了有多久
    2021-02-08 03:02

    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.)

提交回复
热议问题