【问题标题】:Principle of 'printf' [closed]“printf”的原理[关闭]
【发布时间】:2014-11-04 14:06:48
【问题描述】:

我想知道的是编译器和程序是如何工作的。

例如,在“Hello, world!”中举个例子,比如说 hello.c,大家都知道它是这样的: (使用 GNU gcc)

$ gcc -o hello hello.c
$ ./hello

世界你好!

我刚收到一个问题,printf 这个最简单、最熟悉的函数之一是如何定义或使用的。

为了自己找答案,我找到了stdio.h中包含的整个头文件,包含在包含的一个中,包含在包含的一个中。 stdio.h 中包含近 80 个头文件。我会查找每个文件是否包含“printf”这个词。头文件有3个。

stdio.h(本身)

位/stdio2.h

位/stdio-ldbl.h

我不完全了解预处理器语法,但我很确定这些文件中的文本不足以定义printf 函数。例如,在 stdio.h 中,printf 大致是这样引用的:

...
namespace std{
...
extern int printf (const char *__restrict__format, ...);
...
}
...

我知道它说的是语法和声明类型,但我认为它不是printf 的定义或构建。

所以我认为内心深处有一些东西可以回答我的问题,我希望你们中的一些人有一个。

【问题讨论】:

  • 我在这里看不到一个问题。你问定义在哪里?它在图书馆中,您可能有也可能没有来源;你可以看到它here
  • 如果您正在寻找printf 的源代码,您的问题与此问题重复:stackoverflow.com/questions/4867229/… 否则我不确定我是否完全理解您在寻找什么。 printf 的“原则”(原则?)?你这是什么意思?

标签: c gcc c-preprocessor


【解决方案1】:

你是对的,头文件中的声明只是一个前向声明。

这包含函数签名,这是编译器调用函数所需的一切。调用约定、每个参数的类型(因此它可以执行对该类型的隐式转换)等。

实际定义根本不参与编译过程。相反,它是由 C 标准库提供的,称为 libc.a 或 msvcrt.lib。链接器负责确保代码中的函数调用(由编译器转换为 CALL 指令)使用库函数实现的正确地址。

要查看实现的源代码,您需要找出您正在使用的运行时库并下载其源代码。 Visual C++ 的付费版附带 CRT 源代码,它也是用于 Windows 的 mingw 版 gcc 编译器使用的运行时。在 Linux 上,您要下载 glibc 源代码。对于 cygwin,请查看 newlib。嵌入式设备经常使用uclibc 对于一些异国情调的环境,C 库可能是闭源的,尽管这确实会妨碍调试,所以即使许可证有限制,大部分时间源代码也是可用的。

【讨论】:

    【解决方案2】:

    头文件通常包含函数声明,而不是定义。函数的定义将放置在您的平台的标准 C 库中[例如,在 linux 的情况下为 glibc]。您必须为此下载并分析源代码。

    供大家参考,可以参考printf的源码在arch/x86/boot/printf.cinside kernel code [3.17]。了解printf()的实现逻辑背后的想法。

    【讨论】:

    • 很确定他使用的不是内核版本,而是libc版本。
    • 当然,这不是非内核程序使用的定义。
    • @BenVoigt 正在编辑我的答案。谢谢。
    【解决方案3】:

    让我们特别限制C99(不是C++)。

    printfvariadic function。您可以使用stdarg(3) 定义自己的可变参数函数。

    printf 也是托管 C99 中的一个标准函数。当您拥有#include<stdio.h> 时,允许编译器对其进行专门优化。 GCC 正在这样做。见this answer

    顺便说一句,C 标准也定义了vprintf(3)

    最后,存在standard libcfree software 实现。值得注意的是GNU glibcmusl-libc。你可以研究他们对printf 的实现(对于musl-libc:参见文件src/stdio/printf.c 然后src/stdio/vfprintf.c

    你可以研究一下生成的汇编代码hello.s(用一些编辑器或寻呼机看里面)

     gcc -Wall -O -fverbose-asm -S hello.c
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-05
      • 2021-08-08
      • 2023-03-04
      • 2012-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多