【问题标题】:stdio.h contains definition or declaration of functions?stdio.h 包含函数的定义或声明?
【发布时间】:2020-07-29 19:11:18
【问题描述】:

我读到 stdio.h 头文件包含函数声明(带有原型)、宏定义和数据类型的定义。但是当我在 VSCode 中打开文件时,它也包含函数定义——不确定它们是定义还是其他东西。请解释以下内容。这段代码在做什么?更重要的是,是函数定义吗?

mingw_stdio_redirect

int fprintf (FILE *__stream, const char *__format, ...)
{ 
    register int __retval;

    __builtin_va_list __local_argv; __builtin_va_start( __local_argv, __format );

    __retval = __mingw_vfprintf( __stream, __format, __local_argv );

    __builtin_va_end( __local_argv );

    return __retval; 
}

mingw_stdio_redirect

int printf (const char *__format, ...)
{
    register int __retval;

    __builtin_va_list __local_argv; __builtin_va_start( __local_argv, __format );

    __retval = __mingw_vprintf( __format, __local_argv );

    __builtin_va_end( __local_argv );

    return __retval;
}

【问题讨论】:

    标签: c stdio


    【解决方案1】:

    您可能应该添加应该来自MinGW 的完整函数定义,这似乎是:

    __mingw_ovr
    __attribute__((__format__ (gnu_printf, 1, 2))) __MINGW_ATTRIB_NONNULL(1)
    int printf (const char *__format, ...)
    {
      register int __retval;
      __builtin_va_list __local_argv; __builtin_va_start( __local_argv, __format );
      __retval = __mingw_vprintf( __format, __local_argv );
      __builtin_va_end( __local_argv );
      return __retval;
    }
    

    发现与此处的原始GNU stdio.h 完全不同: https://code.woboq.org/userspace/glibc/libio/stdio.h.html

    无论哪种方式,mingw 看起来都在头文件中有函数定义。如果你看 #define __mingw_ovr static __attribute__ ((__unused__)) __inline__ __cdecl __mingw_ovr 是什么 - 看起来这是一个 inline 函数。

    【讨论】:

    • 感谢您的回答。它是完全特定于编译器的吗?此外,即使它是该函数的内联实现,它也会调用 __mingw_vprintf。即使你看到 vprintf 的定义,它也会调用自己。 C运行时库中不存在vprintf的源代码(以编译形式存在)吗?
    • 它是特定于编译器的。 __mingw_vprinf 是一个 extern 函数,默认情况下是 C 中的函数。它的实现在别处。如果您想找到所有答案,只需探索 MinGW 源代码并亲自查看。
    • 你好,你说MinGW在它的头文件中有函数定义。如果这是真的,那么为什么下面的代码仅仅通过提供原型就可以运行得很好? int printf(char *, ...); int main(void) { printf("Hello World");那么C运行时库中不存在定义吗?
    【解决方案2】:

    您引用的代码似乎是函数的定义。

    您创建的头文件应该只包含

    • 定义宏
    • 结构、联合和类型定义名称的定义
    • 声明变量
    • 以原型的形式声明函数

    稍后(一旦你的 C 技能有所提高)你可能还包括

    • inline 函数的定义

    另一方面,编译器实现者可以将任何他们喜欢的东西放在头文件中,只要他们的编译器按照语言标准规定的方式运行。您应该只依赖编译器的文档,而不是通过阅读编译器提供的其他文件可能直觉的任何东西来理解它的行为。

    编译器实现者可以使用他们选择的任何魔法,包括让编译器只知道标准需要什么系统头文件来定义和声明这些头文件的任何实际文件,以及如果他们愿意,他们甚至可能会提供包含虚假或误导性内容的“头”文件。

    【讨论】:

    • 感谢您的回答。它是完全特定于编译器的吗?此外,即使它是该函数的内联实现,它也会调用 __mingw_vprintf。即使您看到 vprintf 的定义(至少在我的头文件中),它也会调用自己。 C运行时库中编译后的形式不是vprintf的源代码吗?如果是这种情况,那么它不只是将调用转移到依赖于库代码的 vprintf 吗?
    【解决方案3】:

    根据C语言标准草案

    7.21 输入/输出

    7.21.1

    简介

    1 标头定义了几个宏,并且 声明了三种类型和许多函数来执行输入和 输出。

    2 声明的类型为 size_t(在 7.19 中描述);

    链接 -> http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf(第 314 页)

    至于代码在做什么:它将格式化的数据打印到流中。

    【讨论】:

    • 这并没有回答关于函数定义的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-25
    • 2018-07-11
    • 1970-01-01
    • 1970-01-01
    • 2011-07-27
    相关资源
    最近更新 更多