丢弃指针上的标志是否合法?
Is It Legal to Cast Away the Sign on a Pointer?
我在一个过时的代码库中工作,该代码库使用 unsigned char*
s 来包含字符串。对于我的功能,我使用了 string
s 但是有一个摩擦:
我无法在旧代码中使用 #include <cstring>
中的任何内容。从 string
复制到 unsigned char*
是一个费力的过程:
unsigned char foo[12];
string bar{"Lorem Ipsum"};
transform(bar.cbegin(), bar.cbegin() + min(sizeof(foo) / sizeof(foo[0]), bar.size()), foo, [](auto i){return static_cast<unsigned char>(i);});
foo[sizeof(foo) / sizeof(foo[0]) - 1] = '[=10=]';
我是否会遇到未定义的行为或别名问题:
strncpy(reinterpret_cast<char*>(foo), bar.c_str(), sizeof(foo) / sizeof(foo[0]) - 1);
foo[sizeof(foo) / sizeof(foo[0]) - 1] = '[=11=]';
[unsigned] char
的严格别名规则有一个明确的例外,因此在字符类型之间转换指针将起作用。
具体在N3690[basic.types]中说任何平凡可复制的对象都可以复制到char
或unsigned char
的数组中,如果再复制回来值是相同的。它还表示,如果将同一个数组复制到第二个对象中,则这两个对象是相同的。 (第二和第三段)
[basic.lval] 表示通过 char
或 unsigned char
类型的左值更改对象是合法的。
我认为 BobTFish 在评论中表达的关于 char
和 unsigned char
中的值是否放错了位置的担忧。 "Character" 值本质上是 char
类型。您可以将它们存储在 unsigned char
中并稍后将它们用作 char
- 但那已经发生了。
(我建议写一些 in-line 包装函数来减少整个事情的噪音,但我认为代码片段是为了说明而不是实际使用。)
编辑:删除使用 static_cast
.
的错误建议
Edit2: 章节。
我在一个过时的代码库中工作,该代码库使用 unsigned char*
s 来包含字符串。对于我的功能,我使用了 string
s 但是有一个摩擦:
我无法在旧代码中使用 #include <cstring>
中的任何内容。从 string
复制到 unsigned char*
是一个费力的过程:
unsigned char foo[12];
string bar{"Lorem Ipsum"};
transform(bar.cbegin(), bar.cbegin() + min(sizeof(foo) / sizeof(foo[0]), bar.size()), foo, [](auto i){return static_cast<unsigned char>(i);});
foo[sizeof(foo) / sizeof(foo[0]) - 1] = '[=10=]';
我是否会遇到未定义的行为或别名问题:
strncpy(reinterpret_cast<char*>(foo), bar.c_str(), sizeof(foo) / sizeof(foo[0]) - 1);
foo[sizeof(foo) / sizeof(foo[0]) - 1] = '[=11=]';
[unsigned] char
的严格别名规则有一个明确的例外,因此在字符类型之间转换指针将起作用。
具体在N3690[basic.types]中说任何平凡可复制的对象都可以复制到char
或unsigned char
的数组中,如果再复制回来值是相同的。它还表示,如果将同一个数组复制到第二个对象中,则这两个对象是相同的。 (第二和第三段)
[basic.lval] 表示通过 char
或 unsigned char
类型的左值更改对象是合法的。
我认为 BobTFish 在评论中表达的关于 char
和 unsigned char
中的值是否放错了位置的担忧。 "Character" 值本质上是 char
类型。您可以将它们存储在 unsigned char
中并稍后将它们用作 char
- 但那已经发生了。
(我建议写一些 in-line 包装函数来减少整个事情的噪音,但我认为代码片段是为了说明而不是实际使用。)
编辑:删除使用 static_cast
.
Edit2: 章节。