Can I make expressions constexpr?

牧云@^-^@ 提交于 2021-01-28 11:16:46

问题


I recently wrote some code which prints a function result to cout. The result could have been evaluated at compile time, but it wasn't:

#include <algorithm>
#include <iostream>

constexpr unsigned int gcd(unsigned int u, unsigned int v)
{
    // ...
}

int main() {
    std::cout << gcd(5, 3) << std::endl;
}

For whatever bizarre reason, this compiles to: (clang -O3 -std=c++17)

main:
    push    r14
    push    rbx
    push    rax
    mov     edi, 5
    mov     esi, 3
    call    gcd(unsigned int, unsigned int)
    mov     esi, eax
    ...

See Compiler Explorer for a live example.

I would like the compiler to evaluate gcd(5, 3) at compile time in order to avoid wasting cycles at runtime, which is obviously possible. I know that I could do the following:

int main() {
    constexpr unsigned g = gcd(5, 3); 
    std::cout << g << std::endl;
}

However, this is unnecessarily verbose. What I would like to do is simply this:

#define CONSTEVAL(expression) // ...

int main() {
    std::cout << CONSTEVAL(gcd(5, 3)) << std::endl;
}

Does there exist any kind of compiler builtin that would make this CONSTEVAL macro possible? Or even better - something fully portable?


回答1:


How about an immediately invoked lambda expression?

#define CONSTEVAL(...) []{ constexpr auto result = __VA_ARGS__; return result; }()

This is effectively a way to produce a constexpr variable to hold the result and evaluate to the variable's value.


This can also be done macro-less via a template, but only if the value can be passed as a template parameter:

template <auto V>
inline constexpr auto consteval_v = V;

Used as consteval_v<gcd(5, 3)>.



来源:https://stackoverflow.com/questions/63637443/can-i-make-expressions-constexpr

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!