捕获 std::initializer_list 的危险使用

问题描述 投票:0回答:1
#include <initializer_list>

int main() {
    std::initializer_list<int> il = std::initializer_list<int>{1, 2, 3};
    return 0;
}

据我了解,您不应该复制

std::initilizer_list
对象,因为它只是一个轻量级代理对象。例如,请参阅此答案:https://stackoverflow.com/a/48046201/11722

在 Clang 15.0.0 中我看到这个警告:

警告:支持本地初始值设定项列表“il”的数组将被销毁 在完整表达式的末尾 [-Wdangling]

但是较新的 clang (或 gcc)似乎没有对此发出警告。 (参见https://godbolt.org/z/hPfKTP7vo

如果我尝试引用内容,

-fsanitise=address
也会在 clang 15 中发现该问题,但在较新的 clang 版本中则不会。底层实现有变化吗?

如果不安全,为什么不禁止复制?

c++ stdinitializerlist
1个回答
0
投票

您所看到的是正在使用的 C++ 标准的不同默认版本,以及这些版本之间的差异。 Clang 15 使用 C++11 或 C++14 作为默认标准。 这意味着

std::initializer_list<int> il = std::initializer_list<int>{1, 2, 3};

将制作一份副本,因此您会收到适当的警告

Clang 16 及更高版本默认为 C++17,它引入了保证复制省略。 这意味着

std::initializer_list<int> il = std::initializer_list<int>{1, 2, 3};

成为

std::initializer_list<int> il{1, 2, 3};

并且不会发生任何复制,您只需直接初始化。

© www.soinside.com 2019 - 2024. All rights reserved.