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

时间:2011-06-04 12:34:57

标签: c string const c99

说到字符串文字,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中的“字符串文字”部分给出了问题的背景。

4 个答案:

答案 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;

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

另一个例子也一样。

请注意const是对象的限定符。关于内存布局,如果它存在与否则没有区别。

答案 3 :(得分:1)

6.4.5 / 6说明了与字符串文字相对应的数组:

  

这些数组是否未确定   是不同的提供他们的元素   有适当的价值。

这是一个允许折叠字符串文字的特定规则。我不知道标准中对于其他对象说同样的事情。