【问题标题】:How to convert string to const unsigned char* without using reinterpret_cast (modern approach)如何在不使用 reinterpret_cast 的情况下将字符串转换为 const unsigned char*(现代方法)
【发布时间】:2021-11-05 07:32:37
【问题描述】:

我有变量input 类型const std::string&

const std::string& input

现在我需要将其转换为const unsigned char*,因为这是函数的输入。

Unitl 现在我有了正确的转换代码:

reinterpret_cast<const unsigned char*>(input.c_str()) 

这很好用,但在叮当声中我收到了警告:

do not use reinterpret_cast [cppcoreguidelines-pro-type-reinterpret-cast]

stringconst char* 更改为const unsigned char* 的正确方法是什么?

【问题讨论】:

  • 正确的方法是使用reinterpret_cast
  • 我很想看看这个功能。我觉得奇怪的是,一个期望 C 字符串的函数需要无符号字符。看起来更像是一个通用缓冲区。
  • 您可以进行 2 次静态转换 - 一次到 const void*,第二次从 const void*const unsigned char* 也可能对您来说更好的容器是 unsigned char 的向量,而不是std::string

标签: c++ reinterpret-cast clang-static-analyzer


【解决方案1】:

将字符串或 const char* 更改为 const unsigned char* 的正确方法是什么?

正确的方法是使用reinterpret_cast。

如果你想避免reinterpret_cast,那么你必须完全避免指针转换,这只有通过解决XY问题才有可能。一些选项:

  • 首先你可以使用std::basic_string&lt;unsigned char&gt;
  • 如果您只需要一个指向 unsigned char 的迭代器而不一定是一个指针,那么您可以使用 std::ranges::views::transform,它对每个元素使用静态转换。
  • 您可以将期望 unsigned char* 的函数改为接受 char*

如果您无法更改 input 的类型并且确实需要 unsigned char* 并且您仍然必须避免重新解释演员表,那么您可以使用转换视图从输入创建 std::basic_string&lt;unsigned char&gt;。但这有潜在的开销,因此请考虑避免 reinterpret_cast 是否值得。

【讨论】:

    【解决方案2】:

    编辑
    显然,与联合的类型双关语是 UB,所以绝对不要这样做。
    (尽管为后代保留答案!)


    要严格回答你的问题,有这样的方法:

    void foo(const unsigned char* str) {
        std::cout << str << std::endl;
    }
    
    int main()
    {
        std::string word = "test";
        //foo(word.data()); fails
        union { const char* ccptr; const unsigned char* cucptr; } uword;
        uword.ccptr = word.data();
        foo(uword.cucptr);
    }
    

    这比reinterpret_cast 更好吗?应该不会吧。

    【讨论】:

    • 更好的问题是:这比reinterpret_cast 更糟吗?肯定是的。某些编译器允许通过联合进行类型双关作为扩展,但它不是标准的可移植 c++
    • 这很可能永远不会失败,因为它所做的只是reinterpret_cast。问题是它教导使用 UB 技术,如果用于更复杂的类型,可能会导致很难找到错误。
    • @KevinAnderson This should do 很明显,只有一个活跃成员可以存在并且你不能切换
    • @m88 是的,还有methods in the standard to do that now 没有UB
    • 在大多数编译器中使用union 的类型双关语主要是因为主要编译同时支持c++ 和c11,并且可能使用C11 规范中的行为描述作为联合部分。但这并没有改变它成为 UB 的任何事情。
    猜你喜欢
    • 2011-02-19
    • 1970-01-01
    • 1970-01-01
    • 2013-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-18
    • 2018-03-27
    相关资源
    最近更新 更多