外部内联函数gcc

3
我正在阅读关于C/C++中内联函数的文章,来源于:http://publib.boulder.ibm.com/infocenter/comphelp/v7v91/index.jsp?topic=%2Fcom.ibm.vacpp7a.doc%2Flanguage%2Fref%2Fclrc07cplr243.htm。以下是相关代码:
inline.h:
   #include<stdio.h>

   extern inline void two(void){  // GNU C uses this definition only for inlining
      printf("From inline.h\n");
   }

main.c:
   #include "inline.h"

   int main(void){
      void (*pTwo)() = two;
      two();
      (*pTwo)();
   }

two.c:
   #include<stdio.h>

      void two(){
      printf("In two.c\n");
   }

输出结果如下:
   From inline.h
   In two.c

这段文字表明:“使用gcc语义进行内联关键字”,可以获得此输出结果。

如果其中一个版本被内联,如何决定调用two()函数的版本?

从输出中可以看出,当直接调用two()时,将调用内联版本。而当使用函数指针时,则会调用非内联版本。是否有一般规则来解决这类调用问题呢?


这是ODR规则的违反。你的程序对同一个函数有两个不同的定义。 - David Rodríguez - dribeas
这难道不违反了“单一定义规则”吗?但是,是的,当函数直接调用时才使用内联函数,当通过指针调用时,它使用 two.c 中的函数。 - Mats Petersson
@MatsPetersson:你能提供编译器供应商的文档支持吗?这是一个编译器扩展,可能比那更奇怪。一个函数是否被内联通常是通过一组启发式算法来确定的,这意味着即使是直接调用,根据周围的代码,也可以使用任一选项。 - David Rodríguez - dribeas
@DavidRodríguez-dribeas:看起来这取决于编译器的版本,但是这里有一个链接,针对gcc 4.3进行了更改:http://gcc.gnu.org/gcc-4.3/porting_to.html - Mats Petersson
2个回答

0

当使用函数指针时,可调用项必须具有地址。编译器必须为函数分配一个地址,因此它将解析为非内联的。

我认为一般规则是您不能使用函数指针调用内联函数,因此如果存在 2 个版本的函数,则在使用函数指针时将调用非内联的函数。请注意,inline 只是一个提示,编译器可以选择忽略它。因此,我认为(如果我错了,请纠正)您无法确保调用内联函数的版本。

当然,命名两个相同的函数可能是一个坏主意。

编辑:启用优化标志可能会更改一些内容。即使使用函数指针,也可能调用内联版本。


0

是的,确实有一个规则。事实上,这正是您所建议的。这个编译器扩展允许单个函数的两个定义共存,并且编译器根据是否内联调用函数来选择使用哪个定义。

特别地,这意味着第一个定义总是被内联,而第二个定义从不被内联。因此,从给定的调用点使用哪个定义完全取决于调用者的细节。在您的情况下,第一次调用是直接调用,而第二次是通过指针调用。编译器决定内联第一次调用而不是第二次调用。这是4种可能决策之一。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接