C 为什么排除标准库后没有错误?

C 为什么排除标准库后没有错误?,c,header-files,C,Header Files,作为C语言的初学者,我在做一些实验,所以我排除了标准库,仍然没有错误。有人能解释一下吗 以下是示例代码: main() { printf("hello, world!\n"); } 此程序在有库或无库的情况下运行相同。为什么?虽然建议在适当的时候包含标准头文件,但不一定需要。函数的默认返回值为int(在代码中忽略该值,这是完全允许的)。函数原型的概念是在存在大量现有程序之后添加到语言中的,因此为了不破坏它们,函数原型是可选的,默认情况下没有原型,这意味着没有编译器验证参数类型是否正确

作为C语言的初学者,我在做一些实验,所以我排除了标准库
,仍然没有错误。有人能解释一下吗

以下是示例代码:

main()
{
    printf("hello, world!\n");
}

此程序在有库或无库的情况下运行相同。为什么?

虽然建议在适当的时候包含标准头文件,但不一定需要。函数的默认返回值为int(在代码中忽略该值,这是完全允许的)。函数原型的概念是在存在大量现有程序之后添加到语言中的,因此为了不破坏它们,函数原型是可选的,默认情况下没有原型,这意味着没有编译器验证参数类型是否正确

您的程序能够与标准库正确链接并正确执行


“Hello World!”是一个非常简单的程序,因此依赖此行为进行任何实质性操作都是错误的。

虽然建议在适当的时候包含标准头文件,但不一定需要。函数的默认返回值为int(在代码中忽略该值,这是完全允许的)。函数原型的概念是在存在大量现有程序之后添加到语言中的,因此为了不破坏它们,函数原型是可选的,默认情况下没有原型,这意味着没有编译器验证参数类型是否正确

您的程序能够与标准库正确链接并正确执行

“Hello World!”是一个非常简单的程序,因此依赖此行为进行任何实质性操作都是错误的;DR--您排除的是头文件,而不是标准库


如果您排除了函数具有正向声明的头文件,您将收到一条警告,肯定会提到函数的“隐式声明”

在这种情况下,(根据最新标准无效),将假定函数返回
int
,并且不会检查传递的参数数量

但是,默认情况下,从源代码生成的对象文件链接到默认的C库
libc
,其中包含函数定义。在本例中,函数返回类型与隐式大小写匹配,因此链接器很乐意将对象文件链接在一起

因此,它成功地完成了链接,并且工作正常

也就是说,
main()
应该是
intmain(void)
,至少要符合标准。

TL;DR--您排除的是头文件,而不是标准库


如果您排除了函数具有正向声明的头文件,您将收到一条警告,肯定会提到函数的“隐式声明”

在这种情况下,(根据最新标准无效),将假定函数返回
int
,并且不会检查传递的参数数量

但是,默认情况下,从源代码生成的对象文件链接到默认的C库
libc
,其中包含函数定义。在本例中,函数返回类型与隐式大小写匹配,因此链接器很乐意将对象文件链接在一起

因此,它成功地完成了链接,并且工作正常



也就是说,
main()
应该是
int main(void)
,至少要符合标准。

您看到警告了吗?生成日志中没有警告。然后您应该使用所有编译器标志来启用警告…出现错误,只是你的编译器没有告诉你,你看到警告了吗?编译日志中没有警告。然后你应该使用所有的编译器标志来启用警告…有一个错误,只是你的编译器没有告诉你,在没有原型的情况下调用变量函数会导致未定义的行为。该代码仅适用于有限的可能函数子集(例如,采用固定数量的int参数并返回int的函数)。根据1999年ISO C标准,调用没有可见声明(变量或非变量)的函数是违反约束的,需要进行诊断。在早期的1989/1990标准中,它不是。默认情况下,许多编译器并不完全符合当前标准。合格的C99或C11编译器必须至少对问题代码发出诊断(可能是非致命警告)。在没有原型的情况下调用可变函数会导致未定义的行为。该代码仅适用于有限的可能函数子集(例如,采用固定数量的int参数并返回int的函数)。根据1999年ISO C标准,调用没有可见声明(变量或非变量)的函数是违反约束的,需要进行诊断。在早期的1989/1990标准中,它不是。默认情况下,许多编译器并不完全符合当前标准。合格的C99或C11编译器必须至少对问题中的代码发出诊断(可能是非致命警告)。该代码通过调用没有原型的可变函数(即使在C89中)导致UB,如果您的答案提到这一点就好了。它很可能不“工作相同”@M.M马特先生,我没有C89的副本,所以我没有添加该部分。无论如何,我提到了无效,因为这是不标准的。我查看了6.5.2.2,C11,但没有得到支持UB的确切报价。您能分享一下您的观点吗?@M.M:在没有可见原型的情况下调用变量函数(即,没有声明或使用空括号的声明)具有从C89/C90开始的未定义行为。此外,在C99及更高版本中,调用任何没有可见声明(可能是原型,也可能不是原型)的函数都是违反约束的;C9