This question already has answers here:
Why cast a pointer to a float into a pointer to a long, then dereference?
(5 answers)
In C, if I cast & dereference a pointer, does it matter which one I do first?
(6 answers)
Closed 4 years ago.
I see this in the code and can't understand what is going here:
T * ptr; // we have some pointer and it has proper adress
...
// Later I see this and I can't understand what is going here
ptr = *((T **)ptr);
Also, later in the code I see *((T**)ptr) = m_address;
What for this construction is used ?
*((T**)ptr)
Thanks!
It means that the author wished they'd written T** ptr instead, and are hacking around the fact that they didn't, by casting the pointer to a different type than that which it was declared with, before dereferencing it. It pretends that ptr points to T** instead of a T*.
There are some occasions on which this type punning is okay (e.g. it's commonly used with the struct sockaddr type to sort of implement polymorphism), but type punning T* to T** is very strange.
In fact, unless T is char, or T has a T* as its first member and there's no padding, it's also a code smell (and, as far as I'm aware, UB).
Avoid.
Related
This question already has answers here:
What is the modern, correct way to do type punning in C++?
(2 answers)
Closed 10 months ago.
I'm worried if my implementation is unsafe or could be improved. Suppose I have an array of bytes (more specifically, std::byte); is casting an element's address to a void pointer and then to any datatype safe?
template <typename To>
constexpr To *byte_cast(std::byte &From) {
return static_cast<To *>(static_cast<void *>(&From));
}
// or rather
template <typename To>
constexpr To *byte_cast(std::byte *From) {
return static_cast<To *>(static_cast<void *>(From));
}
I'm avoiding reinterpret_cast due to its unreliability. Do note that I want to the T * to keep same address of the byte it was cast from.
I do have in mind that the array might not fit the datatype, or maybe endianness might cause a problem, but both will be fixed after my question's answered.
Your paired static_casts are exactly equivalent to a reinterpret_cast. Both cause UB due to strict aliasing violations (except when the target type is char, unsigned char, or std::byte).
The solution is std::bitcast<T>(source). It has the interface similar to what you attempted, except that it returns by value. It's not possible to have a "safe reinterpret_cast" that would return a pointer/reference.
A less modern alternative is std::memcpy.
This question already has answers here:
Why use static_cast<int>(x) instead of (int)x?
(9 answers)
Closed 5 years ago.
is there any reason for using static_cast on non pointer POD data types, like int, float, double?
float v = 100;
int x = (int) v vs int x = static_cast<int>v
Is there any reason/advantage on using that, I saw several answers that covers pointers, but plain POD data I could not find explicit answers about non-pointers.
The best reason I've heard is because you can grep for static_cast and know you will only find casts whereas (int) is much less specific about what's going on in that expression.
Also, C-style casts can remove or add const or volatile and change types without any warnings. If you try to static_cast a const pointer/reference type to a non-const pointer/reference type, you will get a compile error.
This question already has answers here:
Should I use static_cast or reinterpret_cast when casting a void* to whatever
(9 answers)
Closed 9 years ago.
I'm looking through some c++ wrapper code that provides a c api, and I'm finding lots of reinterpret_cast where a static_cast would suffice, e.g.:
struct cpp_object{ void foo(){ /* do something */ } };
/* begin: c api */
typedef void c_object;
void foo(c_object *o)
{
// why this:
reinterpret_cast<cpp_object *>(o)->foo();
// instead of just:
static_cast<cpp_object *>(o)->foo();
}
/* end: c api */
Generally I use reinterpret_cast in rare situations, mostly related to forced bit coersion of buffer contents to a type of know layout and size, known to lie inside buffer contents.
So I ask whether that practice makes sense or sticking to static_cast would be a better one.
In this case the reinterpret_cast is equivalent to a static_cast to cv void* and then another static_cast to the target pointer type. This is an addition to C++11 I believe and wasn't present in C++03, where you had to write the two static_casts to get portable behaviour.
I think in this case you have to use reinterpret_cast because c_object is of type void,
so o is of void *. The compiler can not guess that o is. It has to be a run-time cast.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C++ - Difference between (*). and ->?
What is the difference between this:
(*ptr).f();
and this:
ptr->f();
in c++ where the ptr is a pointer to C++ class which has a function f?
If ptr is a normal pointer, then both are equivalent. ptr->f is a short-cut to dereference the pointer (equivalent to (*ptr)) and access the member of the dereferenced object (equivalent to .f).
If ptr is a class that overloads operator-> and operator*, then they will each call different operator overloads, and so could have different behaviour.
There's no difference at all. (*ptr).f(); is the uglier way to do this.
Actually, if ptr is some smart pointer and its operator* and operator-> are overloaded and execute some side-effects, then you may have a problem with this. But this is really, really bad thing to do. It's as evil as #define true false
Aside from stylistic/typing differences, there is no difference. It's exactly the same as (*ptr).member = 7; vs ptr->member = 7; when using a pointer to a structure or class.
This question already has answers here:
Two different values at the same memory address
(7 answers)
Closed 5 years ago.
I have the following code:
int main(){
const int a = 1;
const int* b(&a);
int* c = const_cast<int*>(b);
*c = 29;
cout<<*c<<a<<*b;
return EXIT_SUCCESS;
}
Why doesnt the value of 'a' change to 29? Does this mean that the constness of a is not removed when const_casting b?
Constant variables also allows the compiler certain optimizations, one of these is that the compiler can keep the value in the registers and not reload it. This improves performance but will not work with variables that changes since these need to be reread. Some compilers even optimize constants by not allocating a variable, but simply replacing the value inline. If you change the variable a to int instead of const int it will work, as it can be read in the documentation about the const_cast operator from IBM:
If you cast away the constness of an
object that has been explicitly
declared as const, and attempt to
modify it, the results are undefined.
You can find more information about the problem you are having and why it doesn't work here:
The const_cast operator (IBM)
C++ const_cast usage instead of
C-style
casts
const_cast
confusion
On a side note it can be noted that if you find yourself in need of using the const_cast there is a good chance that you should reconsider your design instead.