std::initializer_list 的生命周期返回值:GCC 与 Clang 行为
在提供的代码中,您将返回一个 std ::initializer_list 来自函数并观察意外的析构函数行为。具体来说,从函数返回的数组在您可以访问其元素之前就被销毁了。
根本问题源于这样一个事实:根据 C 标准,std::initializer_list 具有一个元素数组,该数组是构造的生命周期与initializer_list相同。这意味着,默认情况下,数组会在函数中的 return 语句末尾被销毁。
GCC 的实现遵循此行为,而 Clang 则不然。 Clang 在返回语句结束后维持数组的生命周期,这不符合标准。然而,Clang 的行为显得不一致,因为对象析构函数从未被调用。
复制列表初始化和编译器解释
带有花括号的 init- 的 return 语句list 通过 copy-list-initialization 初始化返回值,这意味着它复制初始化现有对象。在这种情况下,临时的initializer_list对象是从大括号括起来的列表中复制初始化的。随后,另一个initializer_list对象从第一个对象开始复制初始化。
标准规定数组的生命周期与initializer_list对象相同,但由于创建了initializer_list的多个副本,因此不清楚哪个对象的生命周期决定数组的生命周期。
GCC 通过考虑返回的initializer_list 对象的生命周期来解释标准,导致数组过早销毁。然而,8.5.4/6 中提供的示例表明数组的生命周期应延伸到封闭表达式的末尾,包括接收函数。
编译器行为和标准歧义总结
建议
为了避免意外行为,通常不建议这样做按值返回 std::initializer_list。如果您需要传递可变数量的对象,请考虑使用容器类,例如 std::vector。
以上是为什么 GCC 和 Clang 之间 `std::initializer_list` 返回值的生命周期不同?的详细内容。更多信息请关注PHP中文网其他相关文章!