GCC 警告“always_inline function might not be inlinable”

2019-01-14 09:49:18 +08:00
 XIVN1987

用 GCC 编译一程序,,结果报警告如下:

cmsis/inc/cmsis_gcc.h:58:57: warning: always_inline function might not be inlinable [-Wattributes]
__attribute__( ( always_inline ) ) static inline void __enable_irq(void)

请问这种警告怎么消除??还是说只要使用了__attribute__( ( always_inline ) )就会报警告,,

4224 次点击
所在节点    C
17 条回复
junkman
2019-01-14 10:26:05 +08:00
XIVN1987
2019-01-14 10:33:32 +08:00
@junkman
多谢回答,,StackOverflow 上这个提问我之前就已经搜到过了,,他的问题和我的几乎一样

不过那里似乎并没有解决提问者的问题,,提问者也没有接受其中的某个解答
wutiantong
2019-01-14 10:41:51 +08:00
编译器在抱怨这个__enable_irq 可能无法做 inline,这是个善意的 warning,你首先应该看一下__enable_irq 的内部实现,是什么原因导致它 might not be inlinable 呢?
XIVN1987
2019-01-14 10:58:26 +08:00
@wutiantong
__enable_irq()里面只有一条语句,,肯定能内联
wutiantong
2019-01-14 11:12:34 +08:00
@XIVN1987 https://gcc.gnu.org/ml/gcc-help/2007-01/msg00049.html 这里面提到的第 4 点可能是你这个 warning 的原因。
简单来说,就是访问__enable_irq 的地方可能在__enable_irq 的定义前面?
wutiantong
2019-01-14 11:14:01 +08:00
@XIVN1987 根据他说的“ Consequently, the warning disappears as soon as one uses at least -O2 optimizations.”,你可以先提高优化等级看一下。
wutiantong
2019-01-14 11:29:18 +08:00
@XIVN1987 另外,这个__enable_irq 声明在一个头文件里( cmsis_gcc.h ),另一方面又被 static 修饰成了 internal linkage,这就可能会导致一些问题,可以参考: https://stackoverflow.com/a/2398105
XIVN1987
2019-01-14 11:35:02 +08:00
@wutiantong
多谢热心帮助,,试了下,,优化等级改为 -O2 没作用,,之前一直用的 -Os
wutiantong
2019-01-14 11:48:14 +08:00
@XIVN1987 那我觉得多半是跟 linkage 有关吧
shylockhg
2019-01-14 11:52:36 +08:00
你这个应该是 arm-gcc 的库文件吧,一般不会出现这种警告,你看一下是不是版本或者配置不对
XIVN1987
2019-01-14 13:06:25 +08:00
@wutiantong
@shylockhg

感谢热心帮助,,问题解决了

cmsis_gcc.h 中__enable_irq()的定义如下:
__attribute__( ( always_inline ) ) static inline void __enable_irq(void)
{
__ASM volatile ("cpsie i" : : : "memory");
}


我用 gcc -E 生成了.c 文件的预处理文件,,在预处理文件中__enalbe_irq()的定义变成了
# 58 "../../lib/cmsis/inc/cmsis_gcc.h"
__attribute__( ( always_inline ) ) static void __enable_irq(void)
{
__asm volatile ("cpsie i" : : : "memory");
}

原来的“ static inline ”变成了“ static ”,,inline 没了,,

我就想可能代码某处把 inline 给宏定义了,,所以搜索了下,,果然,在 portmacro.h 中有一行:
#define inline

把这行注释掉问题就解决了

这个文件是厂家的 SDK 里面的,,不知道为什么要这么定义,,
wutiantong
2019-01-14 14:02:38 +08:00
@XIVN1987 我觉得你还是不要改动厂家 SDK 为妙,这里既然涉及了 asm 代码,那么取消 inline 就意味着它在试图自己管理内联优化。
我是不太懂这块知识的,刚看了一个 https://stackoverflow.com/a/36285395
wutiantong
2019-01-14 14:05:11 +08:00
@XIVN1987 其实一楼贴的那个 stackoverflow 链接的最后一个回答就很接近你这个问题:

it is just because of a compiler(arm-none-eabi-gcc) option in Makefile CFLAGS= -D inline
XIVN1987
2019-01-14 14:10:35 +08:00
@wutiantong
这样不就把 inline 这个关键字给#define 成空了吗,,跟 portmacro.h 中的做法“#define inline ”完全等价啊,,
wutiantong
2019-01-14 14:12:38 +08:00
@XIVN1987 是啊,他这里描述的是他的问题(不是解决方案),跟你遇到的问题是很一致的。
XIVN1987
2019-01-14 14:13:29 +08:00
@wutiantong
偶,,抱歉,,我看错了,,我以为你说要加上“ CFLAGS= -D inline ”

确实接近,,效果一样,,只不过一个是在头文件中 define,,一个是在 gcc 命令行选项中 define
wutiantong
2019-01-14 14:21:45 +08:00
@XIVN1987 所以这很可能不是一种 mistake,而是刻意的。在特定场合下( arm 架构?)代码中大量依赖手写的 asm 优化代码,编译器的内联优化可能会搞砸它。 我瞎猜的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/526762

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX