【问题标题】:Don't compile if function failed to be inlined in C++如果函数未能在 C++ 中内联,则不编译
【发布时间】:2023-04-10 01:31:01
【问题描述】:

当强制内联函数因任何原因内联失败时,是否可以强制编译器(CLang/GCC/MSVC)抛出编译错误?

想象下一个代码:

Following code in online compiler!

#include <iostream>

inline __attribute__((always_inline)) int f(int i) {
    if (i <= 0)
        return 0;
    return f(i - 1) + f(i - 2) + i;
};

int main() {
    std::cout << f(10) << std::endl;
}

由于两个递归自调用函数 f() 未能内联,尽管 __attribute__((always_inline)) 指示始终内联。您可以通过上面的链接在汇编程序中看到指令call f(int),这意味着该函数没有内联。

上面的代码是否有可能因为内联失败而引发编译错误(在 CLang/MSVC/GCC 中)?也许可以使用一些编译时static_assert(...) 表达式?

我预计非内联可能还有其他原因,包括函数代码的属性和调用方代码的属性。因此,一般而言,您可能无法提前确定您的函数在所有调用的 100% 中是内联的。因此,我的问题的解决方案将很有用。

也有兴趣解决 lambda 函数内联的相同问题。

【问题讨论】:

    标签: c++ function optimization inline


    【解决方案1】:

    您可以在 Visual Studio 中设置警告级别,以使所有警告的编译失败。 没有用于检查内联故障的断言。

    warning

    更好的答案here

    您可以在 GCC 中使用 -Winline 并打开特定标志,以便将警告视为错误。

    '-Werror= 将指定的警告变成错误。附加了警告的说明符,例如 -Werror=switch 将 -Wswitch 控制的警告转换为错误。此开关采用否定形式,用于对特定警告否定 -Werror,例如 -Wno-error=switch 使 -Wswitch 警告不是错误,即使 -Werror 生效。您可以使用 -fdiagnostics-show-option 选项来使用控制它的选项修改每个可控警告,以确定使用此选项的内容。'

    【讨论】:

    • 你知道任何编译器(CLang/GCC/MSVC)是否存在这种非内联警告命令选项吗?您还知道是否可以告诉编译器仅将这一警告视为错误以停止编译?
    • -Winline 在 GCC 中可用,您可以使用 -Werror 标志将警告转换为类似错误:-Werror=
    • 更新答案
    • 我希望你写的关于警告和命令选项的所有内容都只与 CLang/GCC 相关?你也知道 MSVC 的相同命令选项吗?我只需要为内联警告启用编译错误。另外,也许您知道如何仅针对一个特定功能启用此类错误,而不是代码中的所有 inline 功能?
    • 无论如何,这是一个很好的答案,我支持投票!如果您在回答中涵盖所有 CLang/GCC/MSVC 编译器,那就太好了。如果您知道(并编写)解决方案来仅标记单个特定函数以引发编译错误,那也很好。也许有一些编译指示可以将-Winline 仅应用于一个特定的功能。
    猜你喜欢
    • 1970-01-01
    • 2022-07-06
    • 2017-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-13
    • 2011-06-19
    相关资源
    最近更新 更多