在指针上抛弃标志是否合法?

时间:2016-01-19 13:57:10

标签: c++ c-strings strcpy reinterpret-cast unsigned-char

我正在使用过时的代码库,使用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';

1 个答案:

答案 0 :(得分:2)

[unsigned] char的严格别名规则存在明确的例外,因此在字符类型之间转换指针只会起作用。

具体来说,N3690 [basic.types]表示任何可复制的对象都可以复制到charunsigned char的数组中,如果复制回来,则该值是相同的。它还说如果将相同的数组复制到第二个对象中,则两个对象是相同的。 (第二和第三段)

[basic.lval]表示通过charunsigned char类型的左值更改对象是合法的。

BobTFish在关于charunsigned char中的值是否错位的评论中表达的担忧我认为。 “字符”值本身就是char类型。您可以将它们存储在unsigned char中,然后将其用作char - 但这种情况已经发生。

(我建议写一些内联包装函数来减少整个事情,但我认为代码片段是为了说明而不是实际使用。)

修改:删除使用static_cast的错误建议。

Edit2 :章和节。