2

My C-API takes an array of uint8_t's as config parameter. I'm arriving at its doorsteps with a const char*. How do I now copy the chars over to the uint8_t array in the most unproblematic way? Here's what I've got (contrived ofc):

Demo

#include <cstdint>
#include <cstring>
#include <cstdio>

struct config
{
    uint8_t ssid_[32];
};


auto set_ssid(const char* ssid) {
    // I know this fn has no sideeffects but assume for demonstration
    // purposes that cfg is only initialized here
    config cfg;

    std::strncpy(static_cast<char*>(&cfg.ssid_), ssid, 32);
}

int main()
{
    set_ssid("ComeOver");
}

But this doesn't work as none of the pointer is of void* type:

<source>:14:18: error: invalid 'static_cast' from type 'uint8_t (*)[32]' {aka 'unsigned char (*)[32]'} to type 'char*'
   14 |     std::strncpy(static_cast<char*>(&cfg.ssid_), ssid, 32);
      |              

Is it safe to reinterpret_cast here?

10
  • std::strncpy is C API, you should use some idomatic C++ (std::copy?). Note that your set_ssid function doesn't have any observable effects, so it is not clear what you are trying to achieve. Also I do not like design of this API, also use of it looks like indentation for UB. Commented Oct 13, 2022 at 14:36
  • Possible approach: godbolt.org/z/78WxaWqG8 as you can see compiler sees there is no side effects in set_ssid and removed its code. So please provide code which does something meaningful. Commented Oct 13, 2022 at 14:43
  • See stackoverflow.com/questions/10151834/… Commented Oct 13, 2022 at 14:46
  • @MarekR Thank you, copy_n didn't come to my mind. I know that the function has no sideffects but i zoomed in onto the problematic matter for demonstration purposes and left all baggage out. Commented Oct 13, 2022 at 14:46
  • @MarekR That reads out-of-bounds. Commented Oct 13, 2022 at 16:30

1 Answer 1

0

You should use cfg.ssid_ for the destination buffer instead of &cfg.ssid_. Also you should use reinterpret_cast instead of static_cast, because char * and unsigned char *(uint8_t *) are not pointer-interconvertible.(It's a rule refining various casts. See static_cast conversion.)

So this is recommended.

std::strncpy(reinterpret_cast<char*>(cfg.ssid_), ssid, 32);
// Or simply
std::strncpy((char *)(cfg.ssid_), ssid, 32);
Sign up to request clarification or add additional context in comments.

2 Comments

I mean, out of possible conversions between pointers to a POD, there are pointer-interconvertible cases and not pointer-interconvertible cases.
Yes, but all of these conversions go through void* anyway. reinterpret_cast between pointers is also just a sequence of static_casts through void*. The objects here are not pointer-interconvertible, true, but in order for this to work it is important whether the pointer may alias the object (which it may).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.