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