说到字符串文字,C99标准说(6.4.5.6):
如果这些数组的元素具有适当的值,则这些数组是否不同是未指定的。如果程序试图修改此类数组,则行为未定义。
我找不到类似的警告或对const变量的明确保证。可以表达 &x == &y
在上下文中 const int x=12; const int y=12;
评价为 1
? const变量和字符串文字怎么样(即是 &x == "\014\000\000"
保证是 0
甚至在32位小端平台上)?
对于它的价值,在“字符串文字”部分 这篇博文 给出了问题的背景。
在标准中,平等在第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 a.k.a. C99 + TC3。我不认为版本有所作为。)
据我所知,标准不允许任何类型的两个命名对象具有相同的地址(联盟成员除外)。从6.5.9 / 6:
两个指针比较等于if和only
如果两者都是空指针,则两者都是
指向同一个对象的指针......
字符串文字不是const变量,所以你的第二个问题没有实际意义,我不知道32位和字节序有什么关系。
在
const int x=12;
const int y=12;
x
和 y
是不同的变量(都是const限定的)因此具有不同的地址。
对于另一个例子也是如此。
注意 const
是对象的限定符。关于内存布局,如果它存在与否则没有区别。
6.4.5 / 6说明了与字符串文字对应的数组:
这些阵列是不确定的
是不同的提供他们的元素
有适当的价值观。
这是一个允许折叠字符串文字的特定规则。我不知道标准中对于其他对象说同样的事情。