Why can you do this conversion? - c++

Why can you do this:
class Dummy {
double i,j;
};
class Addition {
int x,y;
public:
Addition (int a, int b) { x=a; y=b; }
int result() { return x+y;}
};
int main () {
Dummy d;
Addition * padd;
padd = (Addition*) &d;
cout << padd->result();
return 0;
}
Why is padd = (Addition*) &d; valid when it will generate a run-time error whenever it gets used afterwards? A quote from cplusplus.com:
Unrestricted explicit type-casting allows to convert any pointer into
any other pointer type, independently of the types they point to.
But why can you convert any pointer into any other pointer type just if you precede the reference with a casting operator?
Talking about that casting operator, how can it convert all types to another type? Does it call a conversion constructor because if so, I do not get it, because both Dummy nor Addition do not have a conversion constructor so how does this operation work then? How many operators does it have and is it the parentheses that are the operator itself, like = is an operator.

These kinds of casts are C style casts, and will let you cast just about anything to anything else. A cast is a statement to the compiler to disregard it's type safety rules and trust that you know best. This is sometimes necessary when the type system can't have all the information it needs to reach the right conclusions. However, if you are lying to the compiler about something's type, then you are producing undefined behavior.
In c++, you should avoid preforming C style casts and prefer the safer c++ alternatives (listed here. Theses casts can't completely protect you from yourself, but they do allow you to communicate the kind of cast you want to preform. Using this extra information, the compiler can warn you if your casts would do something other than what you expect them to do.

When you use:
padd = (Addition*) &d;
the compiler assumes that you, the person in charge, know what you are doing. If you shoot yourself in the foot, that's of your own choosing. The compiler is happy to let you do that.
If you would like the compiler to prevent you from such accidental, shoot-yourself-in-the-foot, situations, use static_cast.
padd = static_cast<Addition*>(&d);
The compiler will let you know that that is not OK.

If you use a C style cast, there is no check for errors or compatibility between the pointers. Also, I think you misunderstand the purpose of the unary operator &, in this case it gives the address of d and is not related to references.
Objects in memory are just bits that the program knows to be some type, if you tell it that it is another type it will not affect anything in the variable.

Related

Return type of void *, is it different in C++ and in C? [duplicate]

Why the following is wrong in C++ (But valid in C)
void*p;
char*s;
p=s;
s=p; //this is wrong ,should do s=(char*)p;
Why do I need the casting,as p now contains address of char pointer and s is also char pointer?
That's valid C, but not C++; they are two different languages, even if they do have many features in common.
In C++, there is no implicit conversion from void* to a typed pointer, so you need a cast. You should prefer a C++ cast, since they restrict which conversions are allowed and so help to prevent mistakes:
s = static_cast<char*>(p);
Better still, you should use polymorphic techniques (such as abstract base classes or templates) to avoid the need to use untyped pointers in the first place; but that's rather beyond the scope of this question.
The value doesn't matter, the type does. Since p is a void pointer and s a char pointer, you have to cast, even if they have the same value. In C it will be ok, void* is the generic pointer, but this is incorrect in C++.
By the way, p doesn't contains char pointer, it's a void pointer and it contains a memory address.
In general, this rule doesn't even have anything to do with pointers. It's just that you can assign values of some type to variables of other types, but not always vice versa. A similar situation would be this:
double d = 0.0;
int i = 0;
d = i; // Totally OK
i = d; // Warning!
So that's just something you have to live with.

Why does static_cast allow downcasts when logically it should refuse them for safety purposes or static_cast is not about safety?

In the following example the compiler accepts the static_cast downcast resulting in undefined behavior while I thought static_cast was all about safety (that C-style casts were unable to provide).
#include <iostream>
class Base {
public:
int x = 10;
};
class Derived1: public Base
{
public:
int y = 20;
};
class Derived2 : public Base
{
public:
int z = 30;
int w = 40;
};
int main() {
Derived1 d1;
Base* bp1 = static_cast<Base*>(&d1);
Derived2* dp1 = static_cast<Derived2*>(bp1);
std::cout << dp1->z << std::endl; // outputs 20
std::cout << dp1->w << std::endl; // outputs random value
}
You use dynamic_cast only really when you are not sure if the cast is going to succeed and you catch exceptions or check for nullptr. However if you are sure your downcasting is going to succeed, the language allows you to use static_cast (which is cheaper). If you were wrong, that is your problem. In an ideal world every cast would succeed in 100% of the time. But we don't live in an ideal world. It's a bit like array subscript. arr[5] means "I am absolutely sure this array has at least 6 elements. Compiler doesn't need to check". If your array was smaller than you expected, that's again your problem.
I thought static_cast was all about safety (that C style cast were unable to provide)
static_cast is safer than a C-style cast. But not because it's impossible to go wrong with it. It's safer because it's only less likely to go wrong. When we write a C-style cast, a compiler will go through this list to appease us:
When the C-style cast expression is encountered, the compiler attempts
to interpret it as the following cast expressions, in this order:
const_cast<new_type>(expression);
static_cast<new_type>(expression), with extensions: pointer or reference to a derived class is additionally allowed to be cast to pointer or reference to unambiguous base class (and vice versa) even if the base class is inaccessible (that is, this cast ignores the private inheritance specifier). Same applies to casting pointer to member to pointer to member of unambiguous non-virtual base;
static_cast (with extensions) followed by const_cast;
reinterpret_cast<new_type>(expression);
reinterpret_cast followed by const_cast.
The first choice that satisfies the requirements of the respective
cast operator is selected, even if it cannot be compiled (see
example). If the cast can be interpreted in more than one way as
static_cast followed by a const_cast, it cannot be compiled. In
addition, C-style cast notation is allowed to cast from, to, and
between pointers to incomplete class type. If both expression and
new_type are pointers to incomplete class types, it's unspecified
whether static_cast or reinterpret_cast gets selected.
The point in favoring static_cast to that, is that you have a finer grained control over the resulting cast, which does grant a measure of added safety. But it doesn't change the fact that the C++ object model requires that static_cast support casting even when undefined behavior is possible. Only dynamic_cast (not on the above list, by the way) has an added bit of safety for polymorphic types, but that's not without overhead.
I don't really know what to tell you. Why does it allow such a cast? For when you need/want one.
Don't want to use it? Don't! You could switch to dynamic_cast (more expensive), or don't cast.
C++ lets you do plenty of things that require thought and care. This is one of them.
But it is still safer than C. The static_cast won't let you cast bp1 to an UrgleBurgle*, for example.
Of course ultimately you can still use the C-style casts if you like. I mean, I wouldn't advise it, but you could. C++ is all about choice (usually between a terrible option and a slightly less terrible option).

Difference between void pointers in C and C++

Why the following is wrong in C++ (But valid in C)
void*p;
char*s;
p=s;
s=p; //this is wrong ,should do s=(char*)p;
Why do I need the casting,as p now contains address of char pointer and s is also char pointer?
That's valid C, but not C++; they are two different languages, even if they do have many features in common.
In C++, there is no implicit conversion from void* to a typed pointer, so you need a cast. You should prefer a C++ cast, since they restrict which conversions are allowed and so help to prevent mistakes:
s = static_cast<char*>(p);
Better still, you should use polymorphic techniques (such as abstract base classes or templates) to avoid the need to use untyped pointers in the first place; but that's rather beyond the scope of this question.
The value doesn't matter, the type does. Since p is a void pointer and s a char pointer, you have to cast, even if they have the same value. In C it will be ok, void* is the generic pointer, but this is incorrect in C++.
By the way, p doesn't contains char pointer, it's a void pointer and it contains a memory address.
In general, this rule doesn't even have anything to do with pointers. It's just that you can assign values of some type to variables of other types, but not always vice versa. A similar situation would be this:
double d = 0.0;
int i = 0;
d = i; // Totally OK
i = d; // Warning!
So that's just something you have to live with.

With or without reinterpret_cast

int main()
{
class_name object;
object.method();
fstream file("writeobject.dat" , ios::out|ios::app);
file.write(reinterpret_cast<char*>(&object), sizeof(object));
return 0;
}
//////////////////////////////////////////////////////////////////////////////////////////
int main()
{
class_name object;
object.method();
fstream file("writeobject.dat" , ios::out|ios::app);
file.write((char*)&bk,sizeof(book));
return 0;
}
What is the difference between above both functions. What is reinterpret_cast is doing here? I don't see any of the difference between output of both main() functions.
A C style cast is nothing but the C++ cast that succeeds from the predefined order of:
const_cast
static_cast
static_cast, then const_cast
reinterpret_cast
reinterpret_cast, then const_cast
In this case they are doing the same thing. However, if you are using C++ it is better to use C++ style of explicit casting because they are more indicative of the intent and also it's always better to be explicit about what casting you need than be at the mercy of the compiler to chose one for you.
There is no functional difference between the C-style cast and the reinterpret_cast in the above case.
However the reinterpret_cast might be considered to be preferred by many because it is explicit in what it is doing, both to the compiler and the other humans reading the code.
Being explicit to the compiler is valuable in cases where automatic conversions might take place at times when it is not desired. Consider:
class Foo
{
public:
operator double() const
{
return mD;
}
Foo () : mD (4.12) {};
private:
double mD;
};
int main()
{
Foo foo;
double d = (double) foo;
double d2 = reinterpret_cast <double> (foo);
}
The code:
double d = (double) foo;
compiles, and when it is run the conversion operator operator double() is called. However the reinterpret_cast will not compile because Foo cannot be converted to a double.
To carry the "be explicit" philosophy forward, in cases where you do want the automatic conversion to be available, you can use a static_cast:
double d3 = static_cast <double> (foo);
This will again call the conversion operator.
Aside from the good answers already given, reinterpret_cast is MUCH easier to search for in the code than (char *), which may occur in other places, never mind that a regex type search will need some escaping to not interpret the * as a wildcard.
More importantly, if you want to find EVERY place that you cast something from one pointer type to another, finding all reinterpret_cast is quite easy, where finding all variants of (int *), (char *), (uint8_t *) and (foo **) would be quite a bit of effort to come up with the right regex to match all those without missing something out and not adding some extra finds that you didn't want.
One uses a C++-style reinterpret_cast, the other a C-style cast. The C++ style is better because it's more explicit about what it's doing, and highlights a potentially dangerous operation with verbose syntax.
In this case they do the same as for this combination of target and source type reinterpret_cast is used for the c-style cast. But just a slight change could change that.
Say you had
const class_name object;
and the first form would not compile while the second switched to "reinterpret_cast, then const_cast". And if the function you pass it to actually modified the data, you'd discover that only at runtime.

TypeCasting Struct and Classes

I am very new to C++. Currently I am reviewing a source code where I saw some typecasting, but I didn't understand it.
Here is the code.
struct str {
char *a;
int b;
};
class F {
public:
char* val;
};
F f1;
Can anyone explain the below Assignement Please.or is that typecasting valid??
str* ptr = (str*) f1->val;
Can anyone explain the below Assignement Please.
It means "pretend that the val pointer points to an object of type str, even though it's declared to point to a completely different type char; give me that pointer and trust that I know what I'm doing".
That's assuming that the real code either declares F * f1;, or accesses it as f1.val; the code you've posted won't compile.
or is that typecasting valid??
If the pointer really does point to an object of the correct type, then it's valid; otherwise, using the pointer will cause the program to fail in all sorts of catastrophic ways.
Typecasting is something that should very rarely be necessary. If you really do need it, you should never (as in absolutely never, under any circumstances) use that C-style cast; it means "force the conversion with no checks whatsoever, as long as there's some way to do it, even if it makes absolutely no sense". Use static_cast or dynamic_cast when you can, and reinterpret_cast or const_cast when you're doing something really dodgy. And don't use any of them unless you know what you're doing, and have a very good reason for circumventing the type system.