隐式声明函数的原因是什么

Da *_*ang 0 c

为什么当字节数malloc很大时函数的返回值会变化?

\n

函数.c:

\n
#include "func.h"\n\nint *func()\n{\n    int *ptr = (int *)malloc(100000000);\n    printf("ptr in func is %p \\n", ptr);\n    return ptr;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

函数.h:

\n
#ifndef _FUNC_H\n#define _FUNC_H\n#include <stdio.h>\n#include <stdlib.h>\n//int *func();\n#endif\n
Run Code Online (Sandbox Code Playgroud)\n

主程序

\n
#include <stdio.h>\n#include "func.h"\n\nint main(int argc, char** argv)\n{\n    int *ptr = func();\n    printf("ptr is %p \\n", ptr);\n}\n
Run Code Online (Sandbox Code Playgroud)\n

编译并运行:

\n
gcc -g main.c func.c -o main\n
Run Code Online (Sandbox Code Playgroud)\n

编译结果为:

\n
main.c: In function \xe2\x80\x98main\xe2\x80\x99:\nmain.c:7:13: warning: implicit declaration of function \xe2\x80\x98func\xe2\x80\x99; did you mean \xe2\x80\x98putc\xe2\x80\x99? [-Wimplicit-function-declaration]\n  int* ptr = func();\n             ^~~~\n             putc\nmain.c:7:13: warning: initialization makes pointer from integer without a cast [-Wint-conversion]\n
Run Code Online (Sandbox Code Playgroud)\n

运行结果:

\n
main.c: In function \xe2\x80\x98main\xe2\x80\x99:\nmain.c:7:13: warning: implicit declaration of function \xe2\x80\x98func\xe2\x80\x99; did you mean \xe2\x80\x98putc\xe2\x80\x99? [-Wimplicit-function-declaration]\n  int* ptr = func();\n             ^~~~\n             putc\nmain.c:7:13: warning: initialization makes pointer from integer without a cast [-Wint-conversion]\n
Run Code Online (Sandbox Code Playgroud)\n

为什么当字节数malloc较小时函数返回相同的值?

\n

函数c

\n
ptr in func is 0x7f557ea88010\nptr is 0x7ea88010\n
Run Code Online (Sandbox Code Playgroud)\n

运行结果:

\n
ptr in func is 0x17af2a0\nptr is 0x17af2a0\n
Run Code Online (Sandbox Code Playgroud)\n

你能告诉我为什么吗?\n我想知道到底是什么原因造成的?

\n

Ing*_*rdt 5

显然您正在 64 位系统上使用sizeof(int *) == 8sizeof(int) == 4。现在,当函数原型丢失(“隐式声明”)时,编译器会假定func()返回int,因此当您调用时,仅使用返回值的int *ptr = func()4 个字节 ( ),将其解释为并强制转换回. 这会导致第一个示例中的错误。sizeof(int)intint *ptr

在第二个示例中,碰巧指针值较小,因此它完全适合 4 个字节,并且在强制转换后,结果再次是相同的指针。尽管如此,它是未定义的行为,您应该始终将警告“隐式声明”视为错误并提供所有必要的原型。

  • @DaWang 没有原型,编译器错误地假设该函数被声明为“int func();”,并且它发出实际上是一个错误的警告(是的,这很奇怪,这是出于历史原因)。如前所述,将包含“隐式”一词的警告视为错误。 (2认同)
  • 该函数存在,因此链接器可以生成可执行文件。由于历史原因,如果编译器看到对未声明的函数的调用,则假定“int func();”(具有返回 int 的未知参数的函数)。 (2认同)
  • 请注意,“调用前没有原型”仅在 C90 中有效(在 C99 中无效,在任何更高版本的标准中均无效)。OP 应至少编译为 C99(几乎是 21 世纪 C),最好是 C11 或 C18。(现在使用 C23 进行生产工作还为时过早。)。OP 也需要使用更严格的编译器警告 - 如果编译器是 GCC 或 Clang,最好是像 `-Werror -Wall -Wextra` 这样的东西作为起点(我会添加更多,但这是一个合理的开始)。 (2认同)