我正在使用过时的代码库,使用unsigned char*
来包含字符串。对于我的功能,我使用了string
但是有一个问题:
我无法在旧代码中使用#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] = '\0';
如果我这样做,我是否会进入未定义的行为或别名问题:
strncpy(reinterpret_cast<char*>(foo), bar.c_str(), sizeof(foo) / sizeof(foo[0]) - 1);
foo[sizeof(foo) / sizeof(foo[0]) - 1] = '\0';
答案 0 :(得分:2)
[unsigned] char
的严格别名规则存在明确的例外,因此在字符类型之间转换指针只会起作用。
具体来说,N3690 [basic.types]表示任何可复制的对象都可以复制到char
或unsigned char
的数组中,如果复制回来,则该值是相同的。它还说如果将相同的数组复制到第二个对象中,则两个对象是相同的。 (第二和第三段)
[basic.lval]表示通过char
或unsigned char
类型的左值更改对象是合法的。
BobTFish在关于char
和unsigned char
中的值是否错位的评论中表达的担忧我认为。 “字符”值本身就是char
类型。您可以将它们存储在unsigned char
中,然后将其用作char
- 但这种情况已经发生。
(我建议写一些内联包装函数来减少整个事情,但我认为代码片段是为了说明而不是实际使用。)
修改:删除使用static_cast
的错误建议。
Edit2 :章和节。