类型限定符对存储位置的影响

时间:2012-10-27 08:36:32

标签: c pointers const storage-class-specifier

如标题中所述,如果type-qualifiers影响声明者的存储位置(stackbss等),我会感到困惑。为了描述更多,我正在考虑以下声明。

int main()
{
   const int value=5;
   const char *str= "Constant String";
}
  • 在上面的代码中,默认storage-class-specifierauto
  • 因此,假设这些常量将在创建时stack-frame main中分配。
  • 通常,堆栈中各种内存位置的pointers可以自由修改其中包含的值。
  • 因此从以上几点可以理解,type-qualifier要么添加一些逻辑来保存所存储元素的constant性质(如果是这样的话是什么?)或constants存储在read-only-portion内存中。请详细说明

更详细的例子

#include <stdio.h>
int main(void)
{
  int val=5;
  int *ptr=&val;
  const int *cptr=ptr;

  *ptr=10;  //Allowed
  //*cptr=10; Not allowed

  //Both ptr and cptr are pointing to same locations. But why the following error?
  //"assignment of read-only location ‘*cptr’"

  printf("ptr: %08X\n",ptr);
  printf("cptr: %08X\n",cptr);
  printf("Value: %d\n",*ptr);
}

在上面的示例中,cptrptr都指向同一位置。但cptr是指向const type qualified整数的指针。在修改cptr的值时,编译器会抛出错误,因为“只读位置的分配'* cptr'”。但我可以使用ptr修改相同位置,如下面的输出所示。请解释

ptr: BFF912D8
cptr: BFF912D8
Value: 10

2 个答案:

答案 0 :(得分:0)

在您的第一个示例中:

int main()
{
   const int value=5;
   const char *str= "Constant String";
}

将存储变量value和字符串文字的位置留给实现。所有C标准保证的是,这些将存储在只读存储器中,可以在文本段,堆栈或任何地方。

在您的第二个案例中:

 int *ptr=&val;
 const int *cptr=ptr;

当您尝试修改*cptr时,编译器不关心cptr指向的实际位置是只读还是可写。所有它关心的是它认为const指向的位置的类型限定符cptr是只读的。

另一种变体:

    const int i = 5;
    p = &i;
   *p = 99;

在这种情况下,编译器允许通过指针修改const值。但这是未定义的行为

答案 1 :(得分:0)

我不会详细介绍你的例子,但是想做一些一般性的评论:

C语言语义仅在一定程度上由编译器和硬件强制执行:程序员有责任避免未定义的行为。

例如,通过从指针中删除constness而不会出现段错误(硬件强制执行)或编译器错误(转换器告诉它),很可能修改自动存储持续时间(堆栈分配)的const限定变量因为你知道你在做什么而闭嘴。

然而,语言限制将被违反,并且代码将在实践中中断,因为优化器将做出不再适用的假设。

然后,有一种误解,即用于访问对象的表达式的类型与操作的定义相关 - 它不是。

有效的输入规则(C996.5§6)实质上使C成为一种非常不健全的类型系统的强类型语言。类型信息(其中包含可变性)由对象(存储位置)本身承载,而不管位置如何被访问。

这使得存储到const限定的存储位置非法(未定义的行为)但技术上可行(不健全的类型系统)。通过指针进行任意类型的惩罚属于违反语言语义的相同类别的操作,但是没有强制执行,因此可能导致奇怪的错误,例如在严格别名的假设下。