计算编译时C字符串的长度。这真的是一个constexpr? [英] Computing length of a C string at compile time. Is this really a constexpr?

查看:228
本文介绍了计算编译时C字符串的长度。这真的是一个constexpr?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在编译时计算字符串文字的长度。为此,我使用以下代码:

I'm trying to compute the length of a string literal at compile time. To do so I'm using following code:

#include <cstdio>

int constexpr length(const char* str)
{
    return *str ? 1 + length(str + 1) : 0;
}

int main()
{
    printf("%d %d", length("abcd"), length("abcdefgh"));
}



<由clang显示结果是在编译时计算的:

Everything works as expected, the program prints 4 and 8. The assembly code generated by clang shows that the results are computed at compile time:

0x100000f5e:  leaq   0x35(%rip), %rdi          ; "%d %d"
0x100000f65:  movl   $0x4, %esi
0x100000f6a:  movl   $0x8, %edx
0x100000f6f:  xorl   %eax, %eax
0x100000f71:  callq  0x100000f7a               ; symbol stub for: printf

我的问题: $ c> length 函数将被评估编译时间?

My question: is it guaranteed by the standard that length function will be evaluated compile time?

如果这是真的,编译时字符串文字计算的门为我打开...例如我可以在编译时计算散列和更多...

If this is true the door for compile time string literals computations just opened for me... for example I can compute hashes at compile time and many more...

推荐答案

常量表达式不是保证在编译时进行评估,我们只有一个非规范的引用草案C ++标准 5.19 常量表达式表示:

Constant expressions are not guaranteed to be evaluated at compile time, we only have a non-normative quote from draft C++ standard section 5.19 Constant expressions that says this though:

[...]> [注意:可以在
翻译过程中评估常量表达式]。

[...]>[ Note: Constant expressions can be evaluated during translation.—end note ]

您可以将结果赋给 constexpr 变量,以确保它在编译时被计算,我们可以从 Bjarne Stroustrup的C ++ 11参考强调我的):

You can assign the result to constexpr variable to be sure it is evaluated at compile time, we can see this from Bjarne Stroustrup's C++11 reference which says (emphasis mine):


除了能够在编译时评估表达式,我们
希望能够 require在
时间;在变量定义前面的constexpr是
(和
意味着const):

In addition to be able to evaluate expressions at compile time, we want to be able to require expressions to be evaluated at compile time; constexpr in front of a variable definition does that (and implies const):

/ p>

For example:

constexpr int len1 = length("abcd") ;

Bjarne Stroustrup总结了我们何时可以确保此 isocpp博客条目,并说:

Bjarne Stroustrup gives a summary of when we can assure compile time evaluation in this isocpp blog entry and says:


[...]正确答案 - 如Herb所说的
- 是根据标准,一个constexpr函数可以
在编译器时间或运行时进行评估,除非它被用作
常量表达式,在这种情况下,必须在
编译时进行评估。为了保证编译时评估,我们必须使用
it,其中需要一个常量表达式(例如,作为数组边界或
作为case标签)或者使用它来初始化一个constexpr。我希望
没有自尊的编译器将错过优化
机会做我最初说:一个constexpr函数是
在编译时评估,如果其所有参数是常数
表达式。

[...]The correct answer - as stated by Herb - is that according to the standard a constexpr function may be evaluated at compiler time or run time unless it is used as a constant expression, in which case it must be evaluated at compile-time. To guarantee compile-time evaluation, we must either use it where a constant expression is required (e.g., as an array bound or as a case label) or use it to initialize a constexpr. I would hope that no self-respecting compiler would miss the optimization opportunity to do what I originally said: "A constexpr function is evaluated at compile time if all its arguments are constant expressions."

这里概述了两种情况,它们应该在编译时进行评估:

So this outlines two cases where it should be evaluated at compile time:


  1. 在需要常量表达式的地方使用它,这似乎是在标准草案中的任何地方,其中短语应为...转换的常量表达式应使用常数表达式,例如数组边界。

  2. 使用如上所述初始化 constexpr

  1. Use it where a constant expression is required, this would seem to be anywhere in the draft standard where the phrase shall be ... converted constant expression or shall be ... constant expression is used, such as an array bound.
  2. Use it to initialize a constexpr as I outline above.

这篇关于计算编译时C字符串的长度。这真的是一个constexpr?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆