【发布时间】:2020-08-11 18:40:24
【问题描述】:
前提
- 我在内存中有一个二进制数据块,表示为
char*(可能从文件中读取,或通过网络传输)。 - 我知道它在特定偏移处包含特定长度的 UTF8 编码文本字段。
问题
我如何(安全且便携地)获取u8string_view 来表示此文本字段的内容?
动机
将该字段作为u8string_view 传递给下游代码的动机是:
- 与
string_view不同,它非常清楚地表明文本字段是 UTF8 编码的。 - 它避免了将其返回为
u8string的成本(可能是免费存储分配 + 复制)。
我尝试了什么
这样做的天真方法是:
char* data = ...;
size_t field_offset = ...;
size_t field_length = ...;
char8_t* field_ptr = reinterpret_cast<char8_t*>(data + field_offset);
u8string_view field(field_ptr, field_length);
但是,如果我正确理解了 C++ 严格别名规则,这是未定义的行为,因为它通过 reinterpret_cast 返回的 char8_t* 指针访问 char* 缓冲区的内容,而 char8_t 不是别名类型。
这是真的吗?
有没有办法安全地做到这一点?
【问题讨论】:
-
据我所知
char在这里很特别。 gcc/clang...是否发出警告? -
@Bernd
char很特别,但我认为它不适用于这里。据我所知,char*可以为任何东西加上别名,但char8_t*不能为字符加上别名。 -
在 C++23 中,我们可能有
std::start_lifetime_as,但我不确定在 C++20 中是否有任何帮助,除了承认你正在努力实现这一目标。 -
看看隐式对象创建,它可能会让你的程序定义明确。
-
如果整个 blob 是 UTF-8 数据,为什么不首先将它作为一堆 char8_t 呢?反正我也不会太担心。真实软件
reinterpret_casts 从网络接收数据或从文件中读取。这是非常普遍的做法,标准是有缺陷的,因为不承认它。
标签: c++ undefined-behavior c++20 strict-aliasing