sml*_*mls 8 c++ strict-aliasing undefined-behavior c++20
char*(可能从文件中读取,或通过网络传输)。我如何(安全且可移植地)获得一个u8string_view来表示此文本字段的内容?
将该字段作为 a 传递给下游代码的动机u8string_view是:
string_view.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);
Run Code Online (Sandbox Code Playgroud)
但是,如果我正确理解 C++ 严格别名规则,这是未定义的行为,因为它char*通过char8_t*返回的指针访问缓冲区的内容reinterpret_cast,而char8_t不是别名类型。
真的吗?
有没有办法安全地做到这一点?
当您访问具有不可接受类型的泛左值的对象时,会发生严格的别名规则。
首先考虑一个明确定义的情况:
char* data = reinterpret_cast <char *> (new char8_t[10]{})
size_t field_offset = 0;
size_t field_length = 10;
char8_t* field_ptr = reinterpret_cast<char8_t*>(data + field_offset);
u8string_view field(field_ptr, field_length);
field [0]+field[1];
Run Code Online (Sandbox Code Playgroud)
这里没有UB。您创建一个数组,char8_t然后访问该数组的元素。
现在,如果所引用的内存对象是data由另一个程序创建的,会发生什么情况?根据标准,这是 UB,因为该对象不是通过指定的创建方式之一创建的。
但您的代码尚未受到标准支持这一事实在这里并不是问题。所有编译器都支持此代码。如果不是,则什么都不起作用,您甚至无法执行最简单的系统调用,因为程序和任何内核之间的大多数通信都是通过字符数组进行的。因此,只要在程序内部访问位于类型的泛左值之间data+field_offset并通过该类型的内存,您的代码就会按预期工作。data+field_offset+field_lengthchar8_t
| 归档时间: |
|
| 查看次数: |
177 次 |
| 最近记录: |