首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果定义在使用之后,为什么XC16编译器要删除内联函数?

如果定义在使用之后,为什么XC16编译器要删除内联函数?
EN

Stack Overflow用户
提问于 2015-04-30 18:48:35
回答 2查看 737关注 0票数 6

在XC16编译器的手册中,说明如下:

编译器只有在将内联函数声明为静态函数以及函数定义先于函数的所有使用时才会消除它们。

在foo.c的顶部我声明

代码语言:javascript
复制
 static inline void nop_10_times(void);

然后在ISR的定义中定义为:

代码语言:javascript
复制
void _CNInterrupt(void)
{
    nop_10_times();

    // rest of function
}

然后,作为测试,我将定义放在文件底部的nop_10_times上。

代码语言:javascript
复制
static inline void nop_10_times(void)
{
    __builtin_nop();
    __builtin_nop();
    __builtin_nop();
    __builtin_nop();
    __builtin_nop();

    __builtin_nop();
    __builtin_nop();
    __builtin_nop();
    __builtin_nop();
    __builtin_nop();
}

当我编译我的项目并查看程序集时,编译器似乎实际上能够完全删除程序集中的函数,并且只保留在ISR中调用它的内联代码。

有人知道它是怎么做到的吗?根据手册中的定义,如果“函数定义先于函数的所有使用”,它将消除内联函数。

EN

回答 2

Stack Overflow用户

发布于 2016-07-09 01:38:07

这两种人工限制似乎都是合理的。在编译器的早期版本中,它们可能是正确的,或者至少在某个规范中是正确的。

  1. 如果函数未声明为静态函数,则可以从当前翻译单元(源文件)外部调用该函数。为此,需要放置一个非内联函数。
  2. 如果函数在定义之前在某个地方被调用,那么编译器在使用时没有足够的信息来内联该函数,只能生成一个函数调用。

这听起来像是优化器的人领先于文档的家伙。当前的优化器可能正在处理完整翻译单元的解析树,并看到它可以删除调用/ret序列。

票数 1
EN

Stack Overflow用户

发布于 2016-07-09 03:01:31

首先,请记住,指令inline只是编译器的提示。编译器可以在需要时随意内联或不内联。

有人知道它是怎么做到的吗?

这就是所谓的双通编译器.内联是否是在解析时间、优化时间、代码发布阶段等进行的,在这里不相关。

根据手册中的定义,如果“函数定义先于函数的所有使用”,它将消除内联函数。

似乎“当且仅当”现在被简单的" if“所取代,因此,如果定义遵循调用,它有时可以内联.或者是优化器的效果,所以内联可以看作是边界效应。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29975478

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档