'printf'原理

时间:2014-11-04 14:06:48

标签: c gcc c-preprocessor

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

例如,在' Hello,world!'比方说,例如hello.c,就像每个人都知道的那样: (使用GNU gcc)

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

Hello world!

我刚才有一个问题是如何定义或使用printf,这是最容易熟悉的功能之一。

为了自己找到答案,我发现整个头文件包含在stdio.h中,并包含在包含的文件中,包括在附带的文件中。 stdio.h中包含近80个头文件。我查找每个文件是否包含单词' printf'。有3个头文件。

stdio.h(本身)

位/ stdio2.h

位/标准输入输出-ldbl.h

我完全不了解预处理器语法,但我非常确定这些文件中的文字不足以定义printf函数。例如,在stdio.h中,printf大致如下所示:

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

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

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

3 个答案:

答案 0 :(得分:5)

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

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

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

要查看实现的源代码,您需要找出您正在使用的运行时库并下载其源代码。 Visual C ++的付费版本附带CRT源代码,这是运行时也用于Windows的gcc编译器的mingw版本。在Linux上,您要下载glibc源代码。对于cygwin,请查看newlib。嵌入式设备通常使用uclibc对于某些特殊环境,C库可能是封闭源代码,虽然这可能会妨碍调试,因此即使许可证具有限制性,大多数时候源代码也可用。 / p>

答案 1 :(得分:0)

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

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

printf也是托管C99中的标准功能。当你有#include<stdio.h>时,允许编译器专门优化它。并且GCC正在这样做。请参阅this answer

BTW,C标准也定义了vprintf(3)

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

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

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

答案 2 :(得分:0)

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

供您参考,您可以在内核代码[3.17]中的printf中引用arch/x86/boot/printf.c的源代码。了解printf()的实现逻辑背后的想法。