在 C 中我们可以拥有的指针的指针数量有多少限制?

What is the limit to the number of pointers to pointers we can have in C?

在 C 中,我知道我们可以用指针来做到这一点:

int *p;          /* an int pointer (ptr to an int) */
int **pp;        /* a pointer to an int pointer (ptr to a ptr to an int) */

甚至:

int **app[];            /* an array of pointers to int pointers */
int (**ppa)[];          /* a pointer to a pointer to an array of ints */
int (**ppf)();          /* a pointer to a pointer to a function returning an int */
int *(*pap)[];          /* a pointer to an array of int pointers */
int **fpp();            /* a function returning a pointer to an int pointer */

但是我们可以做一些像三分球无限的事情吗?例如:

int ***ppp;             /* a pointer to a pointer to an int pointer */
int ****pppp;           /* a pointer to a pointer to a pointer to an int pointer */

...以此类推直到无穷大。

我们可以拥有的指针的指针数量是否有上限?如果可以,上限是多少?

该标准没有规定任何上限。它所说的是编译器至少需要支持 12.

在实际代码中可以认为是无穷大。只有当你编写的程序编写的程序是任何人都不应该阅读的程序时,这才有意义。大多数程序员会说你应该拿三颗星作为警告。没有真正充分的理由,不要超过两个。

我在 gcc 上尝试了 10000,它成功了。我现在正在尝试使用 100000。一件有趣的事情是编译需要很长时间。编译花了几分钟,唯一的声明是一个指针声明,有 10000 个星。

生成C文件的代码:

// gen.c
#include <stdio.h>

int main()
{
    const size_t n = 10000;
    printf("int main(){int ");
    for(size_t i=0; i<n; i++)
        printf("*");
    printf("p;}\n");
}

运行:

$ gcc gen.c -c gen
$ ./gen > stars.c
$ gcc stars.c

回复评论:

这是一个有趣的实验,但我不会进一步研究它。

C 11 标准没有施加最大限制,实际上声明“实施应尽可能避免施加固定的转换限制。” in a footnote.

最小限制由 5.2.4 Environmental limits 给出:

The implementation shall be able to translate and execute at least one program that contains at least one instance of every one of the following limits:18)

  • 127 nesting levels of blocks
  • 63 nesting levels of conditional inclusion
  • 12 pointer, array, and function declarators (in any combinations) modifying an arithmetic, structure, union, or void type in a declaration
  • 63 nesting levels of parenthesized declarators within a full declarator
  • 63 nesting levels of parenthesized expressions within a full expression
  • 63 significant initial characters in an internal identifier or a macro name (each universal character name or extended source character is considered a single character)
  • 31 significant initial characters in an external identifier (each universal character name specifying a short identifier of 0000FFFF or less is considered 6 characters, each universal character name specifying a short identifier of 00010000 or more is considered 10 characters, and each extended source character is considered the same number of characters as the corresponding universal character name, if any)
  • 4095 external identifiers in one translation unit
  • 511 identifiers with block scope declared in one block
  • 4095 macro identifiers simultaneously defined in one preprocessing translation unit
  • 127 parameters in one function definition
  • 127 arguments in one function call
  • 127 parameters in one macro definition
  • 127 arguments in one macro invocation
  • 4095 characters in a logical source line
  • 4095 characters in a string literal (after concatenation)
  • 65535 bytes in an object (in a hosted environment only)
  • 15 nesting levels for #included files
  • 1023 case labels for a switch statement (excluding those for any nested switch statements)
  • 1023 members in a single structure or union
  • 1023 enumeration constants in a single enumeration
  • 63 levels of nested structure or union definitions in a single struct-declaration-list

符合标准的 C 编译器将提供至少 12 级指针间接寻址。