提问人:Alan 提问时间:11/8/2023 最后编辑:Alan 更新时间:11/8/2023 访问量:117
MSVC 接受使用字符串文本初始化的 std::string 数组,但 gcc 和 clang 拒绝
MSVC accepts std::string array initialized with string literal but gcc and clang rejects
问:
我注意到带有 C++20 的 msvc 允许通过字符串文字初始化数组,但 gcc 和 clang 都拒绝它。演示std::string
#include <string>
int main()
{
std::string a[] = "a"; //msvc c++20 accepts while msvc c++17 rejects and gcc and clang all versions rejects this
}
根据 C++ 标准,这里的正确行为应该是什么。
答:
这是指出程序应该格式不正确CWG2824,但当前的措辞(通过P0960R3引入)使其格式良好。
目前 dcl.init.general#16.5 中的措辞说:
否则,如果目标类型为数组,则按如下方式初始化对象。设 x1, . . . , xk 是表达式列表的元素。如果目标类型是未知边界的数组,则将其定义为具有 k 个元素。让 n 表示此潜在调整后的数组大小。如果 k 大于 n,则程序格式不正确。否则,第 i 个数组元素将复制初始化,每 1 个≤ i ≤ k 个 习,每个 k < i ≤ n 的值初始化。对于每 1 个 ≤ i < j ≤ n,与数组第 i 个元素的初始化相关的每个值计算和副作用都先于与第 j 个元素的初始化相关的值计算和副作用排序。
而正确/修订的措辞(如CWG2824中建议的)是:
否则,如果目标类型为数组,则按如下方式初始化对象。初始值设定项的格式应为 ( expression-list )。设 x1, . . . , xk 是表达式列表的元素。如果目标类型是未知边界的数组,则将其定义为具有 k 个元素。让 n 表示此潜在调整后的数组大小。如果 k 大于 n,则程序格式不正确。否则,第 i 个数组元素将复制初始化,每 1 个≤ i ≤ k 个 习,每个 k < i ≤ n 的值初始化。对于每 1 个 ≤ i < j ≤ n,与数组第 i 个元素的初始化相关的每个值计算和副作用都先于与第 j 个元素的初始化相关的值计算和副作用排序。
请注意上面句子中强调的部分,它使代码格式不正确。
请注意,P0960 仅在 C++20 中引入了 dcl.init.general 中的措辞更改。也就是说,缺陷报告适用于 C++20 及更高版本。对于 C++17,不需要对措辞进行任何更改,因为 dcl.init#17.5 已经使程序格式不正确。
上一个:非类型模板参数的无效类型转换
下一个:格式错误的约束表达式
评论
std::size(a)
a[0].size()
std::string b[] = {"a"}; std::cout << a << 1;
std::size(a)
(sizeof(a) / sizeof *(a))
a[0].size()