GCC如何处理内置函数

Peo*_*Sea 18 c c++ gcc

我无法理解GCC内置函数,感到非常困惑.

  • 库函数和内置函数有什么区别?

  • 是否有内置函数可以做但库函数不能做?

  • 我可以编写一个库函数来执行与内置函数printf相同的任务吗?如何判断输入参数的类型(%f,float还是double)?

  • GCC内置函数的机器指令不存储在库中,对吧?他们在哪?

  • 在进行链接时,如何控制这些内置功能代码的放置位置?

  • 为什么有时我会在进行链接时出现错误消息,例如"未定义引用__builtin_stdarg_start"

    // main.c
    #include <stdio.h>
    int main(void) {
      printf("hello world!\n");
      return 0;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    gcc -c main.c,nm表明main.o中没有符号printf,(只有main(T)和puts(U)),为什么?

小智 20

库函数和内置函数有什么区别?

内置函数是编译器直接在编译器本身内部具有一些知识的函数.库函数只是库中定义的函数.可能存在内置函数和同名库函数,因此对于其余的问题,我将"库函数"视为"不是内置函数的库函数".

是否有内置函数可以做但库函数不能做?

是.例如,内置函数可以选择不评估其参数:

int main() {
  int i = 0;
  __builtin_constant_p (++i); // checks whether ++i is a constant expression
                              // does not evaluate ++i
  return i; // returns 0
}
Run Code Online (Sandbox Code Playgroud)

这是因为编译器可以将内置函数转换为其他内容,实际上不需要包含任何函数调用.

我可以编写一个库函数来执行与函数printf相同的任务吗?

有一些内置的知识printf,但在大多数情况下,这是完全可行的.查找如何使用<stdarg.h>.

如何判断输入参数的类型(%f,float还是double)?

您必须信任调用者让格式字符串与其余参数匹配; 你无法检测int到格式字符串期望的时候传递的东西double.但你并不需要处理的区别floatdouble,因为它是不可能通过一floatprintf:它会被转换为double(无论何种格式的字符串)之前printf看到它.printf已经仔细制定了要求,以避免任何编译魔术的需要.

GCC内置函数的机器指令不存储在库中,对吧?

对内置函数的调用在编译时进行转换,但该转换可能只是调用同名库函数.

他们在哪?

如果转换在编译时完成,则没有机器指令.将调用转换为不同的代码,然后编译该代码以生成机器指令.如果结果是对库函数的调用,则该库函数的机器指令是库的一部分.

在进行链接时,如何控制这些内置函数代码的放置位置?

我不明白你的意思.对内置函数的调用在编译时转换为不同的代码,然后将不同的代码编译为包含调用的函数的一部分.它将放在包含函数的其余代码的任何位置.

为什么有时我会在进行链接时出现错误消息,例如"未定义引用__builtin_stdarg_start"

__builtin_stdarg_start尽管有__builtin前缀,但没有内置函数,因此将其视为对库函数的调用.并且没有库函数__builtin_stdarg_start,因此链接器会将此检测为错误.

曾经有一个内置函数__builtin_stdarg_start,但它在几年前被删除了,代码从来就不应该一直使用它.

gcc -c main.c,nm表明main.o中没有符号printf,(只有main(T)和puts(U)),为什么?

那是因为printf作为内置函数和库函数存在.内置函数通常只调用库函数,但有时可以做得更好,包括在您的示例中.在这种情况下,内置函数printf可以在不调用库函数的情况下提供正确的结果printf.


Bla*_*iev 6

大致有2种内建的:对应于标准库函数的那些(malloc,printf并且strcpy都视为默认内置插件),并没有对应的标准库中的-想到__builtin_expect,__builtin_prefetch

第一种内置函数用于使编译器能够发出优化代码来代替相应的调用.知道了来自标准库的每个调用的内部语义,编译器可以决定发出对驻留在库中的函数的调用,或者在其位置发出自定义生成的代码片段,以便原始语义保留,代码运行得更好.

第二种内置函数(也称为"内在函数")支持使用驻留在库中的静态代码难以实现的技巧和优化.它们可以转换为向CPU(__builtin_prefetch,__builtin_expect)提供提示,或者通过更好的编译时内省(__builtin_constant_p,__builtin_types_compatible_p)来增强C语言,或者为某些特定于体系结构的指令(__builtin_ffs,__builtin_popcount)提供更简单,独立于平台的接口.