Come to my `constexpr` class at CppCon 2019! https://cppcon.org/class-2019-constexpr/ Come to my “Moving To C++” Workshop at NDC TechTown 2019!

source

37
Leave a Reply

avatar
37 Comment threads
0 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
0 Comment authors
midgetlyness214Joe Sylveub880Oleksandr Pyshovetsdesertkun Recent comment authors
  Subscribe  
newest oldest most voted
Notify of
devluz
Guest

Could you go more into the bad side effects reinterpret cast might have?

Ryan Krattiger
Guest

Okay, (char*)((void*)ptr) it is then

Denis Priyomov
Guest

Don't like reinterpret_cast? Then use double static_cast:
auto* p = static_cast<Some*>(static_cast<void*>(blob));
Free "uncle Bob" hack 🙂

Nikolay Mihaylov
Guest

assuming you have struct with tho int's, and there are no padding there (yes there will be no alignment), I can not imagine situation where reinterpret cast will fail. I can imagine cases when both reinterpret_cast and memcpy() can fail – for example read-only or protected memory. Or classes.

Tomasz Wiszkowski
Guest

few things to add (that are missing here):1. casting raw stream of bytes to any larger primitive (than chars / uint8s) is susceptible to big/little endian related bugs. those are really ugly to debug, especially if you're encoding lengths this way.2. casting unaligned raw stream to larger primitives will on some CPUs cause an misaligned access violation exception (which is a hardware exception – a trap). This will probably work for you in some cases, but will hurt badly if you need to work with these CPUs.3. in all the cases, including one presented by Jason, this all falls apart… Read more »

MaceUA
Guest

The title of this video is a bit misleading. It's more like "Stop using reinterpret_cast in cases where it can be replaced with std::memcpy".Because sometimes it can't.I don't think it's possible to implement a small-size optimized container like std::function or boost::small_vector without using reinterpret_casts anywhere. When you have an aligned storage and you know that an object of some non-trivial type T has been constructed inside of it, you just have to use reinterpret_cast. There's no other way, even if it's formally UB. (C++17 somehow fixes this with std::launder, but it's quite tricky to get right. And reinterpret_casts are still… Read more »

X Baron
Guest

Reinterpret_cast seems to have a defined behavior for some specific niche uses only. Some other uses are, in practice, implementation defined and therefore often safe?

SeppyTW
Guest

Isn't reinterpret_cast used for type punning in sockaddr_in* to sockaddr* or in cases you need bitcast ?

futube41
Guest

I dont see how this solves the Problem. If the target memory size is not really 3 but smaller this is also undefined behavior.

Head Librarian
Guest

A reinterpret_cast<obj*>(char*) will usually fail with an unaligned access error on anything not an x86.

Orocimaro Say
Guest

So the problem only arises when you use structs with constructor or what ?

TimeGoesBy
Guest

Memcpy? Are you sure compiler can optimize out copying in all cases?

Aman Saxena
Guest

Doesn't memcpy itself use reinterpret_cast (aka C cast) within it?

desertkun
Guest

Not writing a memcmp instead of memcpy and then debugging couple hours straight wondering what the hell is going on, why doesn't this work.

Oleksandr Pyshovets
Guest

std::launder deserves to be mentioned here

ub880
Guest

The given example with the struct and reinterpret_cast is dangerous for another reason: If the elements of the struct are smaller than the default alignment, there may be unused space in the struct (padding).
Yes, __attribute__((packed)) may help.

Joe Sylve
Guest

Thoughts on using placement new for this? https://godbolt.org/z/PKU3Rz

Beau Jamo
Guest

This video is little misleading because there are no sufficient reason why or why not use an interpret cast. Seems like the memcpy solution is a defined behavior because it defined the memory to hold the copied bytes as opposed to binding the struct with two ints into an 8 byte memory when doing reinterpret_cast which could be wrong when an int does not correspond to 4 bytes of memory. I would hope you’ll do a follow up video clarifying or giving more reasons why not use reinterpret_cast.

Mario Schmidt
Guest

I don't get it. How is memcpy better? I still bypass that classes constructor and still have to pray that the alignment is right.

What kind of UB does reinterpret_cast invoke that memcpy doesn't?

Norbert Lange
Guest

Point 1:Ever thought about architectures without unaligned accesses?Those nifty optimization compilers can do, typically break down totally on those architectures, even if you manually tell the compiler to expect correctly aligned data.See: https://godbolt.org/z/vyT-u2 Point 2:how exactly would you use std::bitcast on char arrays/pointers (or to arrays)?S obj = std::bitcast<S>(*reinterpret_cast<(Un)aligned_type_with_same_size as S *>(blob)) ? Point 3:the reinterpret_cast<S > is *not UB, dereferencing that pointer might be. (Which is necessary with bitcast?)ie. if you care for performance and correctness you would use something like the below, particularly if you have more complex structs. void update_data_l(char *blob, int new_value){ // Thats alot better… Read more »

Wolfgang Kundrus
Guest

With C++ you have to know what you are doing. Nothing wrong with that. Go use a different language, if that is not desired.

Tomáš Pružina
Guest

Hm, this probably needs a followup on structure packing, padding, endianness and alignment.
And possibly a footnote on using (de)serializable formats when sending data over the network (gpb, utf-8+json).

Mika Rajala
Guest

In what specific case would the memcpy save us from a crash or memory corruption? I don't write serialization like this at all, since my code needs to run on multiple compilers and machines with different endianess.

Andrew Yameee
Guest

I absolutely hate the fact that type punning is UB for POD types in C++. It's legal in C, there're indeed many cases when it's necessary, and relying on a compiler to optimize away memcpy for mystical purity goal is ironic, since using memcpy is also a hack in itself(the fact that that function is explicitly blessed by the standard). Why not let people static_assert on endianness, CHAR_BIT, sizeof(void*), alignment etc. and use uint*_t type family without sowing FUD about UB? It's C++ for god's sake, you should understand the data layout anyway. Btw, I think there's another way to… Read more »

Krzysztof Małysa
Guest

The problem with memcpy() is that GCC does not fully optimize it. I tried the above example and on GCC it produced 6 mov instead of 1. But the fact is that it will be 6 moves even if the array is bigger than 3.

radio .aktiv
Guest

Good luck trying this in HLS haha. It always depends on what you are writing the code for. You can't always rely on the compiler doing the thinking for you (unfortunately)…

Jakub Skowron
Guest

How do I write this update_data function with additional int index parameter, when I don't know the size of blob (number of S elements)? Then I cannot use just fixed S obj[3], and dynamic allocation probably would not be optimized out.

Arvind Bharti
Guest

I am unable to understand the reasoning and what went wrong with function using reinterpret_cast…

Tom Peters
Guest

I think your sizeofs in the last example are probably missing a ‘*3’

Nyarmith
Guest

Never!!

ChiliTomatoNoodle
Guest

I would have really liked to see a concrete example of where the UB of update_data would actually cause a result other than the anticipated one.

Operation Darkside
Guest

This is too important to watch this tired

Damian Reloaded
Guest

int main()

{

struct s { int a; };

char buffer[8];

auto o = reinterpret_cast<s*>(buffer);

o->a=1000;

return o->a;

}

Rennie Allen
Guest

Have never used reinterpret_cast.

Just0x1b
Guest

I've seen some people using unions to avoid using reinterpret cast, which is also an undefined behavior.

gtdcoder
Guest

What if you just want copy the ints out of the char* into another struct of type S? Is it ok to temporarily reinterpret_cast so you can do a member-wise copy(not a memcpy)?

midgetlyness214
Guest

I don't quite follow the reasoning here. In my own use case where we do use reinterpret_cast is with the use of memory mapped files to share data across different processes. Process 1 populates a struct (trivially copyable) and then copies this entire structure to the memory we just mapped. Process 2 would then simply use reinterpret_cast to view / update that same memory where – according to my understanding at least – the struct does infact exist. Is this still considered UB?