首页 > 解决方案 > 调用 constexpr 与内联函数编译为不同的程序集,禁用优化

问题描述

我遇到了这个很棒的在线编译器资源管理器https://godbolt.org/ ,它显示了代码的汇编版本。我还在阅读有关 C++ 11 新功能的信息,并了解了 constexpr。

看看下面的平方函数:

constexpr int square(int num) {
    return num * num;
}

int main()
{
    int result = square(2);
    return 0;
}

并为两个版本(constexpr 和 inline)生成以下汇编代码

CONSTEXPR https://godbolt.org/z/c69qrevET

main:
        push    rbp
        mov     rbp, rsp
        mov     DWORD PTR [rbp-4], 4   ; compile time constant 4 = 2*2
        mov     eax, 0
        pop     rbp
        ret

内联https://godbolt.org/z/czaKT8fhY

square(int):
        push    rbp
        mov     rbp, rsp
        mov     DWORD PTR [rbp-4], edi
        mov     eax, DWORD PTR [rbp-4]
        imul    eax, DWORD PTR [rbp-4]
        pop     rbp
        ret
main:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        mov     edi, 2
        call    square(int)
        mov     DWORD PTR [rbp-4], eax
        mov     eax, 0
        leave
        ret

我到处都读到这样的函数可以内联,但为什么 asm 版本中有函数调用代码?根据内联定义,应该避免它吗?

标签: c++c++11assemblyinlineconstexpr

解决方案


constexpr除非在需要常量表达式的上下文中使用函数,否则不能保证在编译时执行函数。将您的代码更改为

int main()
{
    constexpr int result = square(2);
    return 0;
}

您会看到不同之处,因为constexpr变量需要使用常量表达式进行初始化。

请注意,优化级别也很重要。


推荐阅读