【问题标题】:Is std::mbstate_t state{} guaranteed to zero-initialize the value?std::mbstate_t state{} 是否保证将值初始化为零?
【发布时间】:2021-09-11 18:40:57
【问题描述】:

mbstate_t 文档says

mbstate_t 类型是一个普通的非数组类型,它可以表示在实现定义的一组支持的多字节字符编码规则中可能出现的任何转换状态。 mbstate_t的零初始化值代表初始转换状态...

还有zero initialization

T () ;
T t = {} ; (2)
T {} ;

2) 作为非类类型和没有构造函数的值初始化类类型成员的值初始化序列的一部分,包括未提供初始化器的聚合元素的值初始化。

所以在我看来,这种组合应该保证

std::mbstate_t state = std::mbstate_t();

(如cppreference std::wcsrtombs documentation 中的示例)或

std::mbstate_t state{};

保证将值初始化为零,因为它是 C 类型并且不能是具有构造函数的类。这是正确的还是我忽略了什么?如果是,为什么其他示例(例如 https://www.cplusplus.com/reference/cwchar/mbsinit/https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/wcsrtombs?view=msvc-160)会这样做

mbstate_t state;
memset(&state, 0, sizeof(state));

【问题讨论】:

  • 这些是 C 的例子,对吧?
  • 最后的那些? cplusplus.com 并不明确,但 MSDN 肯定是 C++。但他们很可能只是因为移植了一个 C 示例而这样做。
  • 标准可能会说些什么,编译器会做一些其他的事情。做一个 std::mbstate_t 状态{};干杯

标签: c++


【解决方案1】:

这似乎是正确的。

The standard says this about mbstate_t:

标题<cuchar>的内容和含义同C 标准库头文件<uchar.h>,除了它声明了 额外的mbrtoc8c8rtomb 函数并且不声明类型 char16_­tchar32_­t


所以,去<uchar.h> 获取C we have

初始转换状态对应,对于一个转换 任一方向,到初始移位状态下的新多字节字符的开头。 零值mbstate_t 对象(至少)是描述 初始转换状态

强调我的。

mbstate_t 的零值初始化是一种有效的方式。

至于为什么其他链接通过memset 进行,对我来说是个谜,但是 further reading 给我们:

但是请注意,其他值存储在 mbstate_t 类型的对象中 也可以表示这个状态

因此,零初始化mbstate_t 似乎描述了一种可以通过多种方式实现的状态,零初始化就是其中之一。


也许您链接的 memset 变体被意外标记为 C++ 而不是 C,因为完整示例似乎是合法的 C。

【讨论】:

    猜你喜欢
    • 2021-04-05
    • 1970-01-01
    • 2021-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-05
    • 1970-01-01
    相关资源
    最近更新 更多