0

type-qualifiers正如标题中提到的,如果影响声明符的存储位置(stack等) ,我有点困惑bss。为了描述更多,我正在考虑以下声明。

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);
}

在上面的例子中,两者都cptr指向ptr同一个位置。但是cptr是指向const type qualified整数的指针。在修改 的值时cptr,编译器会抛出一个错误为"assignment of read-only location '*cptr'"。但我可以使用 修改相同的位置ptr如下面的输出所示。请解释

ptr: BFF912D8
cptr: BFF912D8
Value: 10
4

2 回答 2

0

我不会详细介绍您的示例,但想发表一些一般性评论:

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

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

然而,语言约束将被违反,并且代码将在实践中中断,因为优化器将做出不再成立的假设。

然后,存在一种误解,即用于访问对象的表达式的类型与操作的定义性相关——事实并非如此。

有效的类型规则(C99 6.5 §6)本质上使 C 成为一种类型系统非常不健全的强类型语言。类型信息(其中包括可变性)由对象(存储位置)本身携带,与如何访问该位置无关。

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

于 2012-10-27T09:27:12.513 回答
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 值。但这是未定义的行为

于 2012-10-27T08:51:23.903 回答