【问题标题】:Why is this function evaluated at compile time in g++ but not in clang++为什么这个函数在编译时在 g++ 中被评估,而不是在 clang++ 中
【发布时间】:2019-05-23 19:25:32
【问题描述】:

我目前正在寻找一种将类的名称嵌入到实际对象中的方法。在运行时获取名称不应该花费任何成本。通过使用下面的代码,我在 gcc 中没有额外的成本(因为函数是在编译时评估的)但是由于某种原因,clang 不会在编译时评估代码

我尝试过使用不同的编译器版本,但就我测试所有版本的 gcc 和所有版本的 clang 而言,产生相同的结果(我无法真正测试 MSVC,因为我找不到它所需的标志不生产 6K 装配线)

#include <string>
#include <string_view>
#include <iostream>

template<class T>
constexpr std::string_view get_name()
{
    char const* p = __PRETTY_FUNCTION__;
    while (*p++ != '=');
    for (; *p == ' '; ++p);
    char const* p2 = p;
    int count = 1;
    for (;;++p2)
    {
        switch (*p2)
        {
        case '[':
            ++count;
            break;
        case ']':
            --count;
            if (!count)
                return {p, std::size_t(p2 - p)};
        }
    }
    return {};
}

int main(){
    std::string_view s = get_name<std::string>(); 
    std::cout << s << std::endl;
}

Clang 版本:https://godbolt.org/z/_vY8TD

GCC 版本:https://godbolt.org/z/hhXXWi

我希望 clang 会产生与 gcc 类似的结果,但事实并非如此

【问题讨论】:

    标签: c++ gcc clang c++17 constexpr


    【解决方案1】:

    重点是get_name() 是一个constexpr 函数,而你已经编写了

     std::string_view s = get_name<std::string>(); 
    

    而不是

     constexpr std::string_view s = get_name<std::string>(); 
    

    在第二种情况下(constexpr 变量的初始化)编译器必须(几乎:忽略 as-if 规则)在编译时初始化 s 变量。

    在您的情况下,执行不依赖于运行时已知值,因此编译器有权选择编译时或运行时执行。

    其中一个选择执行编译时,另一个选择执行运行时。

    这两种行为都是合法的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-04
      • 2016-08-30
      • 2015-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-13
      相关资源
      最近更新 更多