constexpr 深度限制与 clang (fconstexpr-深度似乎不起作用)

2024-02-28

有没有办法配置 constexpr 实例化深度? 我正在运行 -fconstexpr-depth=4096 (使用 clang/XCode)。

但仍然无法编译此代码并出现错误: Constexpr 变量 fib_1 必须由常量表达式初始化。 无论是否设置选项 -fconstexpr-depth=4096,代码都会失败。

这是 clang 的错误还是预期会以这种方式表现。 注意:这在 fib_cxpr(26) 之前一直有效,27 是它开始失败的时候。

Code:

constexpr int fib_cxpr(int idx) {
    return idx == 0 ? 0 :
           idx == 1 ? 1 :
           fib_cxpr(idx-1) + fib_cxpr(idx-2); 
}

int main() {
    constexpr auto fib_1 = fib_cxpr(27);
    return 0; 
}

TL;DR:

对于 clang 你需要命令行参数-fconstexpr-steps=1271242并且你不需要超过-fconstexpr-depth=27


计算斐波那契数的递归方法不需要太多的递归深度。所需深度为fib(n)事实上不超过n。这是因为最长的调用链是通过fib(i-1)递归调用。

constexpr auto fib_1 = fib_cxpr(3); // fails with -fconstexpr-depth=2, works with -fconstexpr-depth=3
constexpr auto fib_1 = fib_cxpr(4); // fails with -fconstexpr-depth=3, works with -fconstexpr-depth=4

所以我们可以得出结论-fconstexpr-depth重要的不是设置。

此外,错误消息还表明了差异:

constexpr auto fib_1 = fib_cxpr(27);

编译为-fconstexpr-depth=26,为了确保我们达到该限制,clang 会生成以下消息:

note: constexpr evaluation exceeded maximum depth of 26 calls

但是编译用-fconstexpr-depth=27,有足够的深度,会产生以下消息:

note: constexpr evaluation hit maximum step limit; possible infinite loop?

所以我们知道 clang 区分了两种失败:递归深度和“步数限制”。


“clang 最大步数限制”的 Google 搜索结果显示有关实现此功能的 clang 补丁的页面,包括命令行选项的实现:-fconstexpr-steps。进一步谷歌搜索此选项表明没有用户级文档。

因此,没有关于 clang 算作“步骤”或 clang 需要多少“步骤”的文档fib(27)。我们可以把这个值设置得很高,但我认为这是一个坏主意。相反,一些实验表明:

n : steps
0 : 2
1 : 2
2 : 6
3 : 10
4 : 18

这表明步骤(fib(n)) == 步骤(fib(n-1)) + 步骤(fib(n-2)) + 2. 稍微计算一下,根据这个,fib(27)应该需要 1,271,242 个 clang 步数。所以编译用-fconstexpr-steps=1271242应该允许程序编译,这确实it does http://coliru.stacked-crooked.com/a/baf8408fad71adce。编译用-fconstexpr-steps=1271241会产生与之前相同的错误,因此我们知道我们有一个确切的限制。

An alternative, less exact method involves observing from the patch that the default step limit is 1,048,576 (220), which is obviously sufficient for fib(26). Intuitively, doubling that should be plenty, and from the earlier analysis we know that two million is plenty. A tight limit would be ⌈φ · steps(fib(26))⌉ (which does happen to be exactly 1,271,242).


另一件需要注意的事情是,这些结果清楚地表明 clang 没有对 constexpr 评估进行任何记忆化。海湾合作委员会does https://gcc.gnu.org/ml/gcc-patches/2009-11/msg01504.html,但似乎这根本没有在 clang 中实现。尽管记忆会增加内存需求,但有时(如本例所示)可以大大减少评估所需的时间。我从中得出的两个结论是,编写需要记忆以获得良好编译时间的 constexpr 代码对于可移植代码来说并不是一个好主意,并且可以通过支持 constexpr 记忆和启用/禁用它的命令行选项来改进 clang。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

constexpr 深度限制与 clang (fconstexpr-深度似乎不起作用) 的相关文章

随机推荐

  • 是否可以在 Meta 刷新之前运行 JavaScript 代码

    一直以来 我们都在使用这个可靠的网站重定向 HTML JavaScript 代码
  • 如何在 Swift 中实现范围滑块

    我正在尝试实现范围滑块 并且使用了名为的自定义控件NMR范围滑块 https www cocoacontrols com controls nmrangeslider 但是当我使用它时 滑块根本不出现 难道也是因为它都是用 Objectiv
  • TestNG 跳过测试 - 为什么?

    我正在使用 testng 和 selenium 测试一个网络应用程序 测试主要包括打开应用程序的几个页面 并针对每个页面执行一些特定的活动 因此 我有一个执行 打开页面 测试的抽象基类 并定义了一个用作该测试的数据提供程序的抽象方法 然后有
  • 比较字符串时忽略希伯来语元音

    晚上好 我希望你能帮助我解决这个问题 因为我正在努力寻找解决方案 我有一个单词提供者 他给我元音希伯来语单词 例如 Vowelled 不元音 元音 不元音 与我的提供者不同 我的用户通常无法输入希伯来语元音 我也不应该希望他这样做 用户故事
  • Hill Cipher算法中如何计算逆密钥矩阵?

    我发现很难理解希尔密码算法中矩阵逆的计算方式 我知道这一切都是通过模算术完成的 但不知何故 事情并没有加起来 我真的很感激一个简单的解释 考虑以下希尔密码密钥矩阵 5 8 17 3 请使用上面的矩阵进行说明 你必须学习线性同余定理 http
  • Boost ASIO 和 co_await- 与任何第三方回调一起使用吗?

    一个简单的函数 awaitable
  • 仅在 Android 8.0 及更高版本上资源和布局方向渲染不正确

    我有一个多语言应用程序 主要语言为英语 次要语言为阿拉伯语 我正在打电话setLocale in the onCreate 每一个的Activity在我的应用程序中 public static void setLocale Locale l
  • 从桌面应用程序与 Silverlight 4 LocalMessageReceiver 通信

    我正在为 Silverlight 4 OOB 应用程序开发一个小助手应用程序 安装它可以稍微增强 SL 的功能 改进剪贴板支持 全局热键等 我知道 Silverlight 的本地消息 API 基于 ALPC 这是一个相当未记录的 Windo
  • 方法分配和对象

    我有一个 python 问题 我想将一个方法分配给另一个类的对象 但在这个方法中使用它自己的属性 由于我的项目中有许多具有不同使用方法的容器 不在该示例中 因此我不想使用继承 这将迫使我为每个实例创建一个自定义类 class contain
  • 手动写入后无法使用javascript更新textarea

    我正在编写一个在线应用程序 将一些文本保存到数据库中 大约有 5 个 textarea 和 5 个 input type text 我还实施了搜索以轻松查找和编辑数据库条目 将显示一个新的选择窗口 使用原型和 ajax 当单击其任何条目时
  • 使用 sqlite 进行 Node.js 护照身份验证

    它可以使用node js 护照和sqlite 数据库与会话吗 所有示例仅使用 mongoDb 我想收集 sqlite 中的所有数据 下面是一个使用示例护照本地 https github com jaredhanson passport lo
  • 使用 Jackson 反序列化枚举

    我正在尝试使用 Jackson 2 5 4 反序列化枚举 但失败了 而且我不太明白我的情况 我的输入字符串是驼峰式大小写 我想简单地映射到标准枚举约定 JsonFormat shape JsonFormat Shape STRING pub
  • JBoss AS 7 中的 hibernate 是否需要 c3p0 连接池

    我的项目正处于开始阶段 我在休眠方面遇到了一个大问题 我正在使用 hibernate 4 1 8 Final 和 c3p0 0 9 1 2 我有以下实体类 javax persistence Entity Table name CUSTOM
  • 在 Android 应用程序中提交带有 POST 数据的表单

    我已经在网上搜索一种方法来做到这一点大约一周了 但我似乎无法弄清楚 我正在尝试实现一个应用程序 我的大学可以使用它来允许用户轻松登录校园内的各种服务 目前的工作方式是他们进入在线门户 选择他们想要的服务 填写他们的用户名和密码 然后单击登录
  • 使用 python 检测 Windows 10 上的 USB 设备插入

    我无法获取以下代码检测USB设备插入 http timgolden me uk python win32 how do i detect device insertion html在我的 Windows 10 64 位 计算机上使用 Pyt
  • javascript数组数字键导致过多的“未定义”

    我当前的 webApp 有一个 OOD 系统 每个元素都有一个 id 并放置在每个页面的 elements 数组中 无论 elemenet 放置在哪个页面 每个新元素的 id 都是一个连续的数字 因此 例如 如果我们在一个有 7 个页面的项
  • 如何检查密码强度? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 如何检查密码的强度 作为string 使用 Net框架 基本但合乎逻辑的 enum PasswordScore Blank 0 VeryW
  • 在 JQuery 中查找节点的成本是多少?

    我总是保存结果find 为了避免多次子树遍历 如果我多次需要该值 var a bar div foo find a bar a bar removeClass code here a bar bazz 代替 div foo find a b
  • 如何将 vcl 样式挂钩应用于表单的特定组件?

    我正在使用这个问题的答案的 vcl 风格钩子close button of a tabsheet not supporting vcl styles https stackoverflow com questions 10531153 cl
  • constexpr 深度限制与 clang (fconstexpr-深度似乎不起作用)

    有没有办法配置 constexpr 实例化深度 我正在运行 fconstexpr depth 4096 使用 clang XCode 但仍然无法编译此代码并出现错误 Constexpr 变量 fib 1 必须由常量表达式初始化 无论是否设置