扔掉指针上的标志是否合法
Is It Legal to Cast Away the Sign on a Pointer?
我正在使用一个过时的代码库,该代码库使用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] = ' ';
如果我只是这样做,我是否会遇到未定义的行为或别名问题:
strncpy(reinterpret_cast<char*>(foo), bar.c_str(), sizeof(foo) / sizeof(foo[0]) - 1);
foo[sizeof(foo) / sizeof(foo[0]) - 1] = ' ';
[unsigned] char
的严格混叠规则有一个明确的例外,因此在字符类型之间转换指针将起作用。
特别是在N3690中[basic.types]说任何可复制的对象都可以复制到char
或unsigned char
数组中,如果复制回来,则值是相同的。 它还说,如果您将相同的数组复制到第二个对象中,则两个对象是相同的。(第2和第3段)
[basic.lval] 表示通过 char
或unsigned char
类型的左值更改对象是合法的。
我认为,BobTFish在评论中表达了对char
和unsigned char
中的值是否放错了位置的担忧。 "字符"值本质上是char
类型。 您可以将它们存储在unsigned char
中,并在以后char
使用它们 - 但这已经发生了。
(我建议编写一些内联包装器函数以使整个事情不那么嘈杂,但我认为代码片段是为了说明而不是实际使用。
编辑:删除使用static_cast
的错误建议。
编辑2:章节和经文。
相关文章:
- C ++是否有C ++ 17 OSX 10.13.6的标志
- Visual Studio 中是否有来自代码块的编译器标志的类似物?
- 文件模式标志"ios::app"是否用于删除文件(如果文件已存在)?
- 是否有任何编译器标志可以在下面的代码中用于报告有关 UB 的警告?
- 是否可以使用 GCC 编译具有特定编译器标志的代码文件的一部分?
- 是否有 GCC 标志来发出有关作用域内相同变量重定义的警告?
- 是否有编译器标志可以使较新的 gcc 版本像旧版本一样构建
- while 循环是否在设置标志的情况下运行多次?
- 是否有任何标志指示 QT 主窗口渲染已完成
- 使用 P/调用传递取消标志时是否需要同步
- 检查文件是否在 Makefile 中使用某些标志进行编译
- 检查是否为输入流设置了Skipws/noskipws标志
- 是否可以在Python中使用CV_GUI_EXPANDED标志
- 是否有任何使用 HTTP_SEND_RESPONSE_FLAG_OPAQUE 标志的 HttpSendHttpRespo
- 用错误的标志顺序编译后,是否删除*.cpp文件
- 是否可以使用带有零长度缓冲区ONLOAD_MSG_WARM标志
- 标志-检查是否设置了位并且仅设置了这些位
- 在命令行程序中使用布尔值。找不到定义标志并检查它们是否在参数中的方法
- 是否存在简单的指向布尔值作为线程取消标志的现实情况,无法有效地取消线程?
- Cmake:如何检查是否已定义了一些标志