c++ - 在未使用 constexpr 函数的返回值的情况下,g++ 编译器是否将其视为常规函数?

标签 c++ g++ constexpr

我尝试查看 g++ 编译的 cpp constexpr 函数的编译代码。 我看到,如果函数不返回任何内容,则编译器会将其视为常规函数,但如果它返回一个值并且我将该值分配给 constexpr 变量,则只有在编译时才会计算它。

代码示例:

constexpr int func(int x){
   return x!=0 ? 1: throw "Error";
}

int main(){
    func(2);
}

和编译器输出:

push    rbp
mov     rbp, rsp
mov     edi, 2
call    func(int)
mov     eax, 0
pop     rbp
ret

如您所见,它在运行时调用 func。相反,如果我将函数结果赋值给 constexpr:

constexpr int func(int x){
    return x!=0 ? 1: throw "Error";
}

int main(){
   constexpr int x = func(2);
}

和编译器输出:

main:
    push    rbp
    mov     rbp, rsp
    mov     DWORD PTR [rbp-4], 1
    mov     eax, 0
    pop     rbp
    ret

有人可以解释一下为什么编译器需要这个赋值来在编译时而不是运行时评估函数吗?

最佳答案

编译器可以决定是否在编译时或运行时计算 constexpr 函数。仅当函数在需要编译时常量表达式的上下文中使用(例如使用结果初始化 constexpr 变量)时,编译器必须在编译时计算该函数。

在您的第一个示例中,情况并非如此,并且由于您可能在 Debug模式下编译,因此该函数会像其他函数一样在运行时被调用。

引用自 cppreference (我突出显示):

The constexpr specifier declares that it is possible to evaluate the value of the function or variable at compile time. Such variables and functions can then be used where only compile time constant expressions are allowed (provided that appropriate function arguments are given).

如果您使用例如编译第一个示例-O3 您将看到函数调用已被优化掉。

关于c++ - 在未使用 constexpr 函数的返回值的情况下,g++ 编译器是否将其视为常规函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59537336/

相关文章:

gcc - 链接到 libcuda.so 时出现问题

c++ - g++ : can't link with a main executable file

c++ - C++ 编译器可以缓存 constexpr 函数的结果吗?

android - C++ 方法返回任何数据类型。

c++ - Eclipse SDL 构建错误 : "The program specified in the launch configuration does not exist"

C++03:使用模板构造函数时保留默认复制构造函数

c++ - LNK2019未解析的外部符号求助

c++ - 当 double 为常量时,为什么 g++ -Wconversion 不警告将 double 转换为 long int?

c++ - Constexpr 成员函数

c++ - 使用 std::initializer_list 的 constexpr 的奇怪行为