我知道线程很旧,但几年前这个问题困扰了我一段时间,所以我想投入我的半分钱(如果是这样的话)。
我总是将 C 函数视为具有固定数量的参数,而不管上下文如何,除非它们使用 va_args。也就是说,我相信 main 总是有原型:
int main(int argc, char **argv).
即使没有传递参数,该函数在堆栈上也有这些参数,因为主函数没有函数重载。
C 确实有能力通过假装参数不存在来进行原始重载。在这种情况下,参数仍然被传递并且在堆栈上,但你永远不会访问它,所以它只是减少了源代码的大小。
说int main()只是表示我知道函数可能有参数,但我没有使用,所以我写了int main()。
说 int main(void) 表示 main 肯定没有参数,并暗示有两个不同的函数原型:
int main(void);
int main(int argc, char **argv);
由于 C 没有函数重载,这对我来说有点误导,我不信任其中包含 main(void) 的代码。如果 main 不带任何参数,我不会这样做,在这种情况下 main(void) 完全可以。
注意:在某些实现中,main 中的参数比 argc 和 argv 多,例如 env,但这并不困扰我,因为我知道我并没有明确说这是仅有的两个参数,但那些是最小的参数,可以有更多,但不能更少。这与直截了当地说 int main(void) 大喊大叫,因为这个函数没有参数,这是不正确的,因为它有,它们只是被省略了。
这是我的基本代码:
/* sample.c - build into sample. */
#include <stdio.h>
int main(void)
{
int _argc = *((int *)2686800);
char ***_pargv = (char ***)2686804;
int i;
for (i = 1; i < _argc; ++i) {
printf("%s ", (*_pargv)[i]);
}
return 0;
}
./sample 我显然有论据
该函数显然有传递给它的参数,尽管通过在函数原型中键入 void 明确表示它没有。
如上所述:
(6.7.6.3p10) void 类型的未命名参数的特殊情况作为
列表中只有一项指定该函数没有参数。
因此说函数有 void 作为参数但实际上在堆栈上有参数是矛盾的。
我的观点是参数仍然存在,因此明确断言 main 没有参数是不诚实的。诚实的方法是说 int main(),它不声明它有多少参数,只声明你关心多少参数。
注意 2:_argc、_pargv 依赖于系统,要找到您的值,您必须通过运行此程序找到它们:
/* findargs.c */
#include <stdio.h>
int main(int argc, char **argv)
{
printf("address of argc is %u.\n", &argc);
printf("address of argv is %u.\n", &argv);
return 0;
}
对于您的特定系统,这些值应该保持正确。