代码之家  ›  专栏  ›  技术社区  ›  Omnifarious

为什么这两段使用constexpr的代码,函数和char*会有不同的结果?

  •  17
  • Omnifarious  · 技术社区  · 7 年前

    我有一个代码,如果你把这行注释掉 但这行不通?!

    gcc 8.2 generates an error .

    但是,它们在我看来是一样的。有什么问题吗?这是法律法规吗?

    template <int x>
    struct test_template {
        static int size() { return x; }
    };
    
    constexpr int ce_strlen(char const *s)
    {
        int i = 0;
        while (s[i]) ++i;
        return i;
    }
    
    int joe()
    {
        constexpr int plen = ce_strlen(__PRETTY_FUNCTION__); // This works
        test_template<plen> a; // This declaration is valid.
        test_template<ce_strlen(__PRETTY_FUNCTION__)> b; // But this doesn't work?!
        return a.size() + b.size();
    }
    

    我在想办法的时候碰到了这个 a way to create profile tags for an intrusive profiling system at compile time . 我成功了,但我的最终代码不涉及使用 ce_strlen

    1 回复  |  直到 7 年前
        1
  •  15
  •   Quuxplusone    7 年前

    事实上,正如在评论中所讨论的,这是GCC中的一个bug,但是我想我应该对这个bug的本质有一些额外的见解。在海湾合作委员会 NEWS file

    • __FUNCTION__ __PRETTY_FUNCTION__ printf (__FUNCTION__ ": foo") 必须重写为 printf ("%s: foo", __FUNCTION__)

    但是 __函数__ constexpr.c :

        case DECL_EXPR:
          {
        tree decl = DECL_EXPR_DECL (body);
        if (TREE_CODE (decl) == USING_DECL
            /* Accept __func__, __FUNCTION__, and __PRETTY_FUNCTION__.  */
            || DECL_ARTIFICIAL (decl))
          return NULL_TREE;
        return error_mark_node;
    }
    

    如果它真的是一个变量,我们会期望它通过与以下相同的测试用例:

    constexpr const char* s2 = "TEST";
    constexpr const char* s3 = s2;
    test_template<ce_strlen("TEST")> c;
    test_template<ce_strlen(s2)> d;
    test_template<ce_strlen(s3)> e;