在 C 中,const 变量是否保证在内存中不同?

发布于 2024-11-14 06:12:29 字数 507 浏览 3 评论 0原文

说到字符串文字,C99 标准规定 (6.4.5.6):

如果这些数组的元素具有适当的值,则未指定这些数组是否不同。如果程序尝试修改此类数组,则行为未定义。

我找不到类似的警告或对 const 变量的明确保证。表达式&x == &y 可以在上下文const int x=12; 中使用吗? const int y=12; 计算结果为 1?那么 const 变量和字符串文字(即 &x == "\014\000\000" 保证为 0 即使在 32 位小-字节序平台)?

就其价值而言, 这篇博文给出了问题的背景。

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 appropriate values. If the program attempts to modify such an array, the behavior is undefined.

I couldn't find either a similar warning or an explicit guarantee for const variables. Can the expression &x == &y in the context const int x=12; const int y=12; evaluate to 1? What about a const variable and a string literal (i.e. is &x == "\014\000\000" guaranteed to be 0 even on a 32-bit little-endian platform)?

For what it's worth, the section "String literals" in this blog post gives the context of the question.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

情深缘浅 2024-11-21 06:12:29

据我所知,标准不允许任何类型的两个命名对象具有相同的地址(联合成员除外)。从 6.5.9/6 开始:

当且仅当两个指针比较相等
如果两者都是空指针,则两者都是
指向同一个对象的指针...

字符串文字不是 const 变量,因此您的第二个问题没有实际意义,而且我不明白 32 位和字节序与它有什么关系。

As far as I'm aware, the Standard does not allow two named objects of any type to have the same address (except for union members). From 6.5.9/6:

Two pointers compare equal if and only
if both are null pointers, both are
pointers to the same object...

String literals are not const variables so your secondary question is moot, and I don't see what 32-bitness and endianness have to do with it.

挽袖吟 2024-11-21 06:12:29

在该标准中,相等性在第 6.5.9 节“相等运算符”中讨论,& 在第 6.5.3.2 节“地址和间接运算符”中讨论,const 是在第 6.7.3 节“类型限定符”中讨论。关于指针相等的相关段落是§6.5.9.6:

两个指针比较相等当且仅当两者都是空指针,并且都是指向
相同的对象(包括指向对象的指针和其开头的子对象)或函数,[或超过数组末尾的指针]

& 的唯一定义是“一元 & 运算符产生其操作数的地址。 […]结果是一个指向由其操作数指定的对象或函数的指针。” (第 6.5.3.2.3 节)。不幸的是,“地址”一词没有正式的定义;但是不同的对象(对于 == 定义的等式)具有不同的地址,因为这些地址是根据上面的等式定义不同的指针。

至于 const 的含义,第 6.7.3 节并未表明 const 与对象的构成(对象是“对象中的数据存储区域”)有任何关系。执行环境,其内容可以表示值”(§3.14)。脚注进一步指出“如果从未使用过该对象的地址,则实现不需要为该对象分配存储空间”。尽管这是不规范的,但它强烈表明如果使用地址,则必须为每个对象分配存储空间。

请注意,如果对象是 const volatile,那么很明显(就像 volatile 一样清楚)它们不能具有相同的地址,因为 const volatile 对象在实现过程中是可变的。 (第 6.7.3.10 节有一个使用 const volatile 的示例。)

即使在非易失性情况下,const 也仅表明程序的这一部分不允许修改对象,并不是说对象一般是只读的。要将 const 对象的存储与其他对象合并,大胆的实现者必须保证没有任何东西可以修改该对象。对于在具有单独编译的实现中具有外部链接的对象来说,这是相当困难的(但当然,我们正在远离标准并进入实践中不会发生的领域)。

如果这是关于编写 C 程序,那么您可以通过为对象赋予不同的值来增加机会:

const int x = __LINE__;
const int y = __LINE__;

如果这是关于 C 的理论模型,我会努力使对象不同。您必须通过在论文(扩展版本)的一个段落中总结答案来证明此选择的合理性。

另一方面,如果这是关于编写一个优化编译器,我怀疑合并常量会伤害许多现实世界的程序。我会选择合并到嵌入式编译器中,用户习惯于在边缘情况下保持安全,并且节省的内存可能是不可忽略的。我反对合并到托管平台中,因为任何收益都可以忽略不计。

(参考文献来自 N1256 又名 C99+TC3。我不认为版本有所不同。)

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

他不在意 2024-11-21 06:12:29

xy

const int x=12;
const int y=12;

是不同的变量(均为 const 限定),因此具有不同的地址。

另一个例子也是如此。

请注意,const 是对象的限定符。关于内存布局,有或没有都没有区别。

In

const int x=12;
const int y=12;

x and y are different variables (both const-qualified) and therefore have different addresses.

The same for the other example.

Note that const is a qualifier for an object. Regarding memory layout, it makes no difference if it's there or not.

梦途 2024-11-21 06:12:29

6.4.5/6 描述了与字符串文字对应的数组:

未指定这些数组是否
只要它们的元素是不同的
有适当的值。

这是允许折叠字符串文字的特定规则。我不知道标准中是否有任何内容对其他对象说了同样的事情。

6.4.5/6 says of the arrays corresponding to string literals:

It is unspecified whether these arrays
are distinct provided their elements
have the appropriate values.

So that's a specific rule allowing string literals to be folded. I don't know of anything in the standard that says the same thing for other objects.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文