-2

I have a string variable

string pr00("")

and I want to call the method fun1

fun1(demo *dm)

demo defined as follow

typedef struct 
{
    char pr00[100];
}demo;

is that safe to call this method as

fun1((demo*)pr00);

thanks and BR

KostasA
  • 5,204
  • 6
  • 23
  • 29
  • 8
    No, this is not safe. This is **very** unsafe, `std::string` is a complex structure, very different then your `demo` struct. For starters they are of different size. Not to mention that the standard explicitely marks casting between unrelated structs/classes as UB. Don't do that. – freakish Jun 04 '18 at 09:03
  • 1
    no it isn't safe to cast a `std::string` to a `char*` use `std::string::data()` – Tyker Jun 04 '18 at 09:05
  • Maybe [this](https://stackoverflow.com/questions/1466073/how-is-stdstring-implemented) SO question may be interesting for you. – YesThatIsMyName Jun 04 '18 at 09:08
  • why would you think it is? You wouldn't randomly cast other classes to be other random classes would you? – UKMonkey Jun 04 '18 at 09:30

3 Answers3

2

No, this is unsafe. Because std::string's members are not the same as demo.

But you can define a constructor to implicitly convert std::string to demo type.

#define MAX_SIZE    100
struct demo 
{    
    demo(const std::string& str)
    {
       memset(pr00, 0, MAX_SIZE);

       if (str.length() < MAX_SIZE)
       {
           strncpy(pr00, str.c_str(), str.length());
           pr00[str.length()] = 0;
       }
    }

    char pr00[MAX_SIZE];
};

Now you can write code as this:

std::string name("hello world");
demo d(name);
zhm
  • 3,513
  • 3
  • 34
  • 55
  • 2
    With a user-defined constructor , demo is not a POD, see [https://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special](https://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special). – cwschmidt Jun 04 '18 at 09:22
  • @cwschmidt Good catch! But as I read in the thread, it mentions *user-defined copy-assignment operator and destructor*, not constructor. – zhm Jun 04 '18 at 09:31
  • 1
    @MartinZhai Picking the specific quotes: "An aggregate is an array or a class (clause 9) with no user-declared constructors" ... "A POD-struct is an aggregate class" – UKMonkey Jun 04 '18 at 09:35
  • In the `str.length() >= MAX_SIZE` case you are leaving `pr00` uninitialised – Caleth Jun 04 '18 at 09:35
  • @Caleth Yes, but we can't know the length of string in compile time. In order to deal with strings with any length, we need to use dynamic allocated char string. I'm not sure if that's what OP wanted. – zhm Jun 04 '18 at 09:39
  • @UKMonkey Oops.. My mistake. – zhm Jun 04 '18 at 09:40
  • @MartinZhai I mean you can zero initialise it, or copy 99 characters and nul terminate, or copy 100 characters. – Caleth Jun 04 '18 at 09:42
1

No, fun1((demo*)pr00); is undefined behaviour. You will need to copy (at most 100) characters from pr00 into a demo and pass a pointer to that to fun1

demo dm;
std::copy_n(pr00.data(), std::min(100, pr00.size()), dm.pr00);
fun1(&dm);
Caleth
  • 52,200
  • 2
  • 44
  • 75
0

I'm assuming string means std::string.

It's not just unsafe but invalid. The question has fun1((demo*)pr00).

This is an attempt to cast a structure to a pointer. Illegal and if your compiler has settings where that is allowed, turn them off.

There's a slightly more interesting question regarding fun1((demo*)&pr00). Notice the & taking the address of pr00.

It's still undefined behaviour but at least it's converting pointers between unrelated structures.

You could define void fun2(char*cp) and call fun2((char*)&pr00) though what you can safely do with cp inside fun2() has a number of restrictions.

You shouldn't make any assumptions about the layout of std::string so you should' access cp (and particularly not write to it) with any assumption of what you might find.

Persixty
  • 8,165
  • 2
  • 13
  • 35