4

我对 C 中的指针表示有疑问。如果我正确理解了 C11 标准的这一段:

C11 (N1570),§ 6.2.5.28,类型,p。36

类似地,指向兼容类型的合格或不合格版本的指针应具有相同的表示和对齐要求。

我推断类型int *int const *具有相同的表示,但类型int **int const **. 我对吗 ?

如果是这样,我想知道为什么这两种类型在第二种情况下没有相同的表示?我的意思是,intand具有相同的表示形式,与 andint const同上,那么and有什么问题?int *int const *int **int const **

4

2 回答 2

1

正如 Bart van Ingen Schenau 所说,我认为标准化委员会希望尽可能少地限制指针的表示。从编译器的角度来看,对 and 有一个不同的表示是很有用的int *int const *因为常量可以放在更大或更小的内存中,因此可以使用更小的指针指向更小的内存。然而,这意味着%s格式说明符printf应该有两个版本,一个用于常量字符串,一个用于非常量字符串。这会破坏很多遗留代码,我的猜测是标准化委员会缺乏将其强制执行到社区的勇气。可能是正确的。由于没有令人信服的理由为 and 强制执行相同的表示int **int const **他们就这样离开了。然而,为这些指针使用不同的表示几乎没有用处,除非可能用于某些极端情况应用程序。

他们也可能已经决定只有 char *并且char const *应该具有相同的表示,只是为了 save %s,但也许还有一些其他接口也要求指向其他原始类型的指针相等。

类似地,在某些系统上,希望对全局内存中的某些内容、堆栈上的某些内容和堆中的某些内容具有不同的指针表示。然而,在 C 中可以使用指针,它可以包含这样的指针(你可以再次想到可变参数),因此至少需要一个可以表示所有指针的指针表示。

在 C 内存空间上的 Embedded-C 扩展中引入了显式允许程序员从不同的数据总线获取数据,而无需可以表示所有数据的指针类型。这样的内存空间也可以用于为常量、堆等指定专用内存。从而允许更有效的指针表示。

我的一位同事还提到,仍然允许使用 K&R 原型,或者更好的是没有原型。在这种情况下,编译器无法检测到参数声明和使用之间的表示差异。这无疑会导致遗留软件中许多未被发现的问题。这些问题可以通过要求在参数传递(包括可变参数)上使用通用表示来解决,例如在可变参数中为floattodouble所做的,但这也会损害不同表示的预期效率。

于 2013-05-26T09:19:51.930 回答
1

您是正确的,int *并且int const *需要使用相同的表示,int **并且int const **没有该要求。

不需要相同表示的原因很可能是为了避免对奇怪架构的 C 编译器施加不必要的限制,同时使 C 的规范不会比需要的更难理解。

请注意,在某些实现中,例如char*int*具有不同的大小。这可能导致了一个基本假设,即指向不同类型的指针可以具有不同的表示形式,然后针对指向兼容类型的指针和指向结构/联合的指针对该基本规则进行了例外处理。

据我所知,除了DS9K的编译器之外,没有任何实现可以利用int **and的这种余地。int const **

于 2013-05-22T10:33:21.027 回答