在 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 级指针间接寻址。
在 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 级指针间接寻址。