为什么这两段使用constexpr、__PRETTY_FUNCTION__和char *的代码会有不同的结果呢?
Why do these two pieces of code using constexpr, __PRETTY_FUNCTION__ and char * have different results?
我有这段代码,如果您注释掉注释为“But this doesn't work?!”的行,它编译得很好,但如果不这样做,编译器生成错误。
至少,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
.
确实,正如评论中所讨论的那样,这是 GCC 中的一个错误,但我想我会就此错误的性质提出一些额外的见解。在 GCC NEWS file 中有这一行:
__FUNCTION__
and __PRETTY_FUNCTION__
are now treated as variables by the parser; previously they were treated as string constants. So code like printf (__FUNCTION__ ": foo")
must be rewritten to printf ("%s: foo", __FUNCTION__)
. This is necessary for templates.
但是 __PRETTY_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;
我有这段代码,如果您注释掉注释为“But this doesn't work?!”的行,它编译得很好,但如果不这样做,编译器生成错误。
至少,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
.
确实,正如评论中所讨论的那样,这是 GCC 中的一个错误,但我想我会就此错误的性质提出一些额外的见解。在 GCC NEWS file 中有这一行:
__FUNCTION__
and__PRETTY_FUNCTION__
are now treated as variables by the parser; previously they were treated as string constants. So code likeprintf (__FUNCTION__ ": foo")
must be rewritten toprintf ("%s: foo", __FUNCTION__)
. This is necessary for templates.
但是 __PRETTY_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;