datatype pointers using *(datatype*) [duplicate] - c++

This question already has answers here:
Regular cast vs. static_cast vs. dynamic_cast [duplicate]
(8 answers)
Closed 7 years ago.
i started to learn a bit more about c++ and lately i see really often stuff like (DWORD)(x+y);
example:
int number = 10;
int pointer;
pointer = *(int*)(number);
std::cout << "number: " << number << std::endl;
std::cout << "pointer: " << pointer << std::endl;
getchar();
this makes a exception, i know, but could someone properly explain those action to me? like (int) and (DWORD) etc.. or, recommend me a book? thanks!

Casting or type conversion is changing a variable from one datatype to another.
There are two types. implicit and explicit casting.
Implicit type conversion, also known as coercion, is an automatic type conversion by the compiler.
double a = 3.4;
int b = a; //convert 'a' implicitly from 'double' to 'int'
Explicit type conversion is a type conversion which is explicitly defined within a program
int a = 3;
double b = (int)a; //convert 'a' explicitly from 'int' to 'double'
A DWORD is a 32-bit unsigned integer. I'ts just another type.
A pointer is another datatype.
void *a;
int *b = (int*)a; //explicit
void *c = b; //implicit
About cating: https://en.wikipedia.org/wiki/Type_conversion#Implicit_type_conversion
About book recommendation: The Definitive C++ Book Guide and List

Related

Assigning pointers of different types

Why is the initialization of lp illegal?
int i = 42;
long *lp = &i;
Xcode prompts that I cannot initialize a variable of type 'long *' with an rvalue of type 'int *'.
Why?
Your Xcode is on point, those are different types, it is indeed an illegal initialization, C++ does not allow for assignment (or initialization) of pointers with different types.
That said, you can explicitly convert the assignee:
int i = 42;
long *lp = reinterpret_cast<long*>(&i);
About your seach for reasoning, I'll say those are the rules of the language, they are there to protect you (and your program), not to make your job more difficult, a pointer to long used to operate (dereference, increment, etc.) in an address which is used to store an int will invoke undefined behavior. A compiler is not obliged to treat pointers of different types in the same way. Differences in size, alignment, etc. can occur.
As largest_prime_is_463035818 stated the obligation to explicitly cast tries to prevent mistakes.
This, however, only allows you to compile your program, it doesn't remove the possibility of it being ill-formed.
Simple example:
int i = 42;
int *p = &i;
long *lp = reinterpret_cast<long*>(&i);
long *lpc = (long*)(&i);
std::cout << "int pointer => " << *p << "\n"; // fine, prints 42
std::cout << "long pointer => " << *lp << "\n"; // not fine, prints random vaue *
std::cout << "long pointer 2 => " << *lpc << "\n"; // not fine, same *
As you can see in the example above your compiler was right, that is indeed a problematic cast, tricking the compiler to allow the conversion made the program compile, but fail to produce a consistent result.
* I also tried this in a Windows platform and the results were good, maybe because a long in my platform is only 4 bytes, same as an int, maybe not, the point is, you only should do this when you are absolutely certain that the types are interchangeable.

static_cast<type>() vs type () [duplicate]

This question already has answers here:
Regular cast vs. static_cast vs. dynamic_cast [duplicate]
(8 answers)
C++ cast syntax styles
(10 answers)
Closed 4 years ago.
In the "Programming: Principles and Practice Using C++", "Section 8.5.7 Argument checking and conversion" the following example is given as evidence on how to properly convert types, but never clearly explains why you would use int() vs static_cast<int>() to convert from a double to an int. However, I'm still unclear on the benefits of static_cast<int>() vs int().
void ff(int x);
void gg(double y) {
ff(y); // how would you know if this makes sense?
int x=y; //how would you know if this makes sense?
}
void ggg(double x) {
int x1 = x; // truncate x
int x2 = int(x);
int x3 = static_cast<int>(x); // very explicit conversion (17.8)
ff(x1);
ff(x2);
ff(x3);
ff(x); // truncate x
ff(int(x));
ff(static_cast<int>(x)); // very explicit conversion (17.8)
}
I checked section 17.8, but still didn't find clarity on this topic. Can someone help? I'm looking for a solution that compares static_cast with function-style cast.
Explicit type conversion is permissive [expr.type.conv]:
If the initializer is a parenthesized single expression, the type conversion expression is equivalent to the corresponding cast expression.
On the other-hand if you use it only for fundamental types it should be fine. It should be never used in generic code:
template<class T,class...Args>
auto dangerous_construct(Args...args){
return U(args...); //here we could have a reinterpret_cast
}
int i;
double* v = dangerous_build<double*>(&i);//no compilation error!
If you look for a short and safe cast use the brace-style:
template<T,class...Args>
auto safe_construct(Args...args){
return U{args...}; //OK equivalent to a static_cast + narrowing checks.
}

using const_cast to pass const data argument to a function whose parameter is a non-const [duplicate]

This question already has answers here:
What does a const cast do differently?
(6 answers)
Closed 9 years ago.
We can use const_cast to pass const data argument to a function whose parameter is a non-const.
int fun(int* ptr)
{
return (*ptr + 10);
}
int main(void)
{
int val = 10;
const int *ptr = &val;
int *ptr1 = const_cast <int *>(ptr);
cout << fun(ptr1);
return 0;
}
Output:
20
But, we can achieve the casting in the following way also,
int fun(int* ptr)
{
return (*ptr + 10);
}
int main(void)
{
int val = 10;
const int *ptr = &val;
int *ptr1 = (int *)ptr;
cout << fun(ptr1);
return 0;
}
Output:
20
Then, what is the need for using const_cast in this particular scenario?
Is there any advantage of using const_cast only in this particular scenario?
Because when you specify const_cast you explicitly tell that you wish to remove constness, while old-style cast allows you to cast anything to anything. See https://www.securecoding.cert.org/confluence/display/cplusplus/EXP05-CPP.+Do+not+use+C-style+casts
The evil C-style cast will do just about any conversion that's remotely possible. By using that, you give up any hope of the type system catching mistakes in your code.
The C++ casts restrict the types of conversions that are possible, reducing the scope for accidentally casting to the wrong thing.
For example, this cast will compile, but give some kind of undefined behaviour if you try to use the pointer:
double * bad = (double*)ptr;
while this cast will fail to compile, since const_cast can't do type conversions:
double * less_bad = const_cast<double*>(ptr);
The casts work (more or less) as follows:
static_cast allows you to undo "safe" conversions; for example, converting a pointer to a base class to a pointer to a derived class, or void* to a typed pointer. It doesn't allow conversions that don't make sense under the type system.
reinterpret_cast allows wonkier conversions, such as converting pointers to integers or unrelated pointer types. Use it with care, if you need abandon the type system to do something funky.
const_cast allows you to remove const and volatile qualifiers, while not allowing type conversions.
dynamic_cast allows conversion between pointers or references to polymorphic types, with a run-time check that the conversion is valid. This is the only "safe" cast, as it cannot give a wrongly-typed result.
The evil C cast allows anything that static_cast, reinterpret_cast and const_cast can do, and more besides. The syntax is hard to spot, or to search for, so use this if you want to hide the true horror of your code and drive maintenance programmers into insanity.

Requirement for explicit type conversion

For static_cast, Is it true that, unless there exist a built-in type conversion function, you cannot use static_cast to perform conversion. But you can do a reinterpret_cast for a type, considering the return type is valid.
int main()
{
WORD word;
HWND hwnd = static_cast<HWND>(word); // error
HWND hwnd = reinterpret_cast<HWND>(word); // ok, considering a valid handle is returned.
}
Do the explicit type conversions done with static_cast require a conversion function unlike reinterpret_cast?
reinterpret_cast just allows you to convert completely unrelated types. It just treats the chunk of memory as another type. So it is very unsafe to use it, since it just doesn't give you any compile or runtime errors but just causes (usually) crash
static_cast provides compile time check of validity of an cast. If an type cannot be treated as another type then static_cast gives you an compile time error when attempting an cast.
It does implicit conversions between types (such as int to float, or pointer to void*), and it can also call explicit conversion functions (or implicit ones).
So you can say that it can do the implicit casts for which there is an implicit conversion inbuilt function present. It is usually considered as replacement for c-style casting if that is the confusion.
The C++ casts make most sense when casting pointers and references.
Concrete examples
void foo (Base & b) {
if (b .is_a_Foo ())
static_cast <Foo &> (b) .bar ();
else
b .do_default_bar ();
dynamic_cast <Baz &> (b) .something (); // throws if invalid conversion
}
char data [4];
* reinterpret_cast <float *> (data) = 1.23;
The Windows API is a horrible hack from top to bottom -- in your example, reinterpret_cast is faithful to the original intent (and highlights it for the world to admire) and it basically means "throw away the type system and use the raw bits: trust me".
Basically static_cast allocates memory for compatible class size of destination type and fills it with what is possible, but without any checking that new object is complete. Let me give you an example:
class A {
public:
int a;
};
class B : public A {
public:
int c;
int b;
};
int main()
{
A *a = new A;
a->a = 5;
B *b = new B;
b->a = 6;
b->b = 7;
b->c = 8;
B* bb = static_cast<B*>(a);
A* aa = static_cast<A*>(b);
cout << bb->a << endl; // 5
cout << bb->b << endl; // scrap value from memory
// member b was not initialized, because it was not found in A
cout << aa->a << endl; // 6
return 0;
}
In your example static cast is invalid, because hwnd is void * and word is unsigned short. For c++ casts any type can be considered as a class;
reinterpret_cast works always. It is just a binary copy

C++: can't static_cast from double* to int*

When I try to use a static_cast to cast a double* to an int*, I get the following error:
invalid static_cast from type ‘double*’ to type ‘int*’
Here is the code:
#include <iostream>
int main()
{
double* p = new double(2);
int* r;
r=static_cast<int*>(p);
std::cout << *r << std::endl;
}
I understand that there would be problems converting between a double and an int, but why is there a problem converting between a double* and an int*?
You should use reinterpret_cast for casting pointers, i.e.
r = reinterpret_cast<int*>(p);
Of course this makes no sense,
unless you want take a int-level look at a double! You'll get some weird output and I don't think this is what you intended. If you want to cast the value pointed to by p to an int then,
*r = static_cast<int>(*p);
Also, r is not allocated so you can do one of the following:
int *r = new int(0);
*r = static_cast<int>(*p);
std::cout << *r << std::endl;
Or
int r = 0;
r = static_cast<int>(*p);
std::cout << r << std::endl;
Aside from being pointers, double* and int* have nothing in common. You could say the same thing for Foo* and Bar* pointer types to any dissimilar structures.
static_cast means that a pointer of the source type can be used as a pointer of the destination type, which requires a subtype relationship.
Floating point-to-integer conversion is supported, so int a = static_cast<int>(5.2) is fine. However, it's a conversion - the underlying data types are completely incompatible. What you're asking is for the runtime to convert a pointer to an 8-byte structure to a pointer to a 4-byte structure, which it can't do in any meaningful way.
That having been said, if you really want to interpret your double as an integer, int* r = reinterpret_cast<int*>(p) will work fine.
You can convert between a double and an int with static_cast<>, but not between pointers to different types. You can convert any pointer type to or from void * with static_cast<>.
The rationale may be that int * and double * are often effectively arrays, and the implementation doesn't know how big the array is.
Because you used double * instead of double
The * after it means that you are declaring a pointer, which is vastly different from a regular double.
C++ can not safely static_cast a pointer to a different type of pointer like that.
If you are wanting to do this kinda thing, you must first dereference the variable.
r=new int(static_cast<int>(*p));
You must use new because a double and an integer can not reside in the same memory space(sanely)