clang 忽略属性 noinline

Posted

技术标签:

【中文标题】clang 忽略属性 noinline【英文标题】:clang ignoring attribute noinline 【发布时间】:2019-02-01 14:50:53 【问题描述】:

我希望 __attribute__((noinline)) 在添加到函数时确保该函数被发出。这适用于 gcc,但 clang 似乎仍然内联它。

这里是一个例子,你也可以open on Godbolt:

namespace 

__attribute__((noinline))
int inner_noinline() 
    return 3;


int inner_inline() 
    return 4;


int outer() 
    return inner_noinline() + inner_inline();




int main() 
    return outer();

使用-O3 构建时,gcc 会发出inner_noinline,但不会发出inner_inline

(anonymous namespace)::inner_noinline():
        mov     eax, 3
        ret
main:
        call    (anonymous namespace)::inner_noinline()
        add     eax, 4
        ret

Clang 坚持内联它:

main: # @main
  mov eax, 7
  ret

如果向函数添加参数并让它们执行一些琐碎的工作,clang 尊重 noinline 属性:https://godbolt.org/z/NNSVab

noinline 不应该独立于函数的复杂程度吗?我错过了什么?

【问题讨论】:

clang 是否支持noinline 属性? list of attributes中没有自己的分类,但是如果你在那里搜索noinline,你会发现它被多次提及。 另外,查看带有参数的版本,如果我在那里删除它,这两个函数都是内联的。所以 clang 似乎至少知道这一点。 相关:github.com/emscripten-core/emscripten/issues/3409 【参考方案1】:

__attribute__((noinline)) 阻止编译器内联函数。它不会阻止它进行不断的折叠。在这种情况下,编译器能够识别出不需要调用inner_noinline,无论是作为内联插入还是外联调用。它可以将函数调用替换为常量3

听起来您想改用optnone 属性,以防止编译器应用最明显的优化(就像这个优化一样)。

【讨论】:

这和@YSC 的评论是有道理的。有趣的是,clang 和 gcc 似乎对什么是内联有不同的看法。

以上是关于clang 忽略属性 noinline的主要内容,如果未能解决你的问题,请参考以下文章

clang-format 如何忽略外部 C?

如何使用 clang-format 3.9 忽略文件或目录

为啥clang忽略__restrict__?

如何让clang忽略c-c++不兼容错误?

clang 忽略包含文件的 -std=c++11 标志

当我使用 CMake 和 ninja 构建时,clang++ 会忽略 -MD 标志