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.
Related
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.
I have this following code
size_t returnSize(const char* s)
{
string string(s);
return string.size();
};
size_t returnSize(const int& i)
{
return sizeof(i);
};
template<typename T>
vector<char> Serialize(const T& t)
{
T* pt = new T(t);
vector<char> CasttoChar;
for (int i =0 ;i<returnSize(t);i++)
{
CasttoChar.push_back(reinterpret_cast<const char*>(pt)[i]);
}
delete pt;
return CasttoChar;
};
template<typename T>
T DeSerialize(const vector<char> cstr)
{
T* a = (T*)(&cstr[0]);
return *a;
}
int _tmain(int argc, _TCHAR* argv[])
{
int x = 97;
vector<char> c = Serialize(x);
cout << DeSerialize<int>(c) << endl;
string k = "blabla";
vector<char> c3 = Serialize(k.c_str());
cout << DeSerialize<const char*>(c3) << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
//output is
//97
//blabla
Is this line T* a = (T*)(&cstr[0]); safe?
Also, I tried reinterpret_cast<T*>(&cstr[0]); instead of T* a = (T*)(&cstr[0]); but compiler complained about not being able to convert const char* to int*. so why does the C style cast work?
Refer the standard
Why reinterpret_cast fails?
5.2.10 Reinterpret cast [expr.reinterpret.cast]
The reinterpret_cast operator shall not cast away constness (5.2.11).
An expression of integral, enumeration, pointer, or pointer-to-member
type can be explicitly converted to its own type; such a cast yields
the value of its operand.
Should I use C Cast?
No. Using C Cast instead of C++ Cast is always unsafe. You are trying to remove the constness of an Object which is an UB.
Using reinterpret_cast, will actually trap this error and advise you of during compile time of the potential pitfall.
You should actually use const_cast in this situation. Its the only legal way to convert a const object to a non const object
But Why does a C Cast works
Quoting from the accepted answer from the Question When should static_cast, dynamic_cast and reinterpret_cast be used?
A C-style cast is defined as the first of the following which
succeeds:
const_cast
static_cast
static_cast, then const_cast
reinterpret_cast
reinterpret_cast, then const_cast
So fortunately, it tries the const_cast first.
The C-style cast works because it takes many steps in order to make the cast succeed. It uses the first of the following that succeeds:
const_cast
static_cast
static_cast + const_cast
reinterpret_cast
reinterpret_cast + const_cast
In this case, it's doing the most 'powerful' cast, a reinterpret_cast to const int * followed by const_cast to int*.
The reinterpret_cast alone won't compile, because you're casting away const-ness. The const_cast is required to cast to int*. Doing a reinterpret_cast to const int* would be fine, however.
As an aside, what you're doing is generally unsafe, unless you're using a compiler extension to ensure that any user-defined type you're deserializing to isn't padded.
C style casting in c++ is not a good idea precisily because you go past the checks that prevent you from removing a const or changing the type arbitrary. If you want to make the code work as is you first need to const_cast and then reinterpret_cast, but really try to avoid const casting. To avoid the warning using reinterpret_cast simply declare a as const T*.
Stick to C++ casts. The reason the reinterpret_cast didn't work is you were casting away constness, which isn't cool; you have to use a const_cast for that and you just shouldn't. C casts ignore this.
Having said that, what are you trying to achieve here? You have effectively casting to a char array and memcpying without the efficiency that would bring.
Sorry to chime in here, but your code is broken in several ways, and the casting is just one of them. Concerning the casting, as soon as you use the conversion from/to vector on something that is not just a simple int or so but requires a constructor it will fail. In any case, a two-step conversions from char const* to void const* to T const* is unfortunately necessary.
Now, other problems:
Try the whole thing with a zero-size string. This should now fully answer your actual question, too: No, it's not safe.
You are returning a pointer to a char from DeSerialize<char const*>(). This pointer points into memory owned by the given vector, which is passed by value and after returning from that function ceases to exist! It is pure luck that it seems to work.
Even if you managed to somehow return a char const* from the function, think about who owns that memory now. The point is that this owner must also release the memory. Consider using std::string and making the char const* variant not compile using a specialization of your template.
In general, if you mean this code earnest, begin adding unit tests. It might slow you down now but avoids errors while you go, thus saving time overall. Search for "test-driven development".
There is nothing that assures that the string is NUL-terminated.
Don't use new/delete unless you have to, prefer "plain" stack variables. If you do, take care of properly releasing the memory in case of exceptions (from push_back()). Use auto_ptr (C++98) or unique_ptr (C++11) to make sure the memory is released correctly.
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.
Which is safer to use?
int main()
{
const int i=5;
int *ptr;
ptr=(int*)&i; <------------------- first
ptr=const_cast<int*>(&i); <-------------------Second
return 0;
}
It's safer in the sense that you won't get a cast that's something other than just removing const:
int main()
{
const char i=5;
int *ptr;
ptr=(int*)&i; // the compiler won't complain
ptr=const_cast<int*>(&i); // will fail, since `i` isn't an int
return 0;
}
which doesn't necessary mean that the const_cast<> is safe:
const int i=5;
int main()
{
int const& cri(i);
int& ri = const_cast<int&>(cri); // unsafe
ri = 0; // will likely crash;
return 0;
}
They are entirely equivalent, except that C-style casts present more of a maintenance headache over the const_cast. If the code were frozen in time, they would be identical. The Standard says that the C-style cast may devolve to static, reinterpret, or const cast or a combination of the three, or a strange funky cast that can access private bases for some reason. The point is, in this use case it is exactly equivalent to const_cast.
I'm not sure about safety - I'm sure someone is more well-versed in this than I am - but C++-style casts are part of the language standard and should always be preferred over C-style casts (as a matter of both style as well as readability).
To amend my answer, it appears that C++-style casts are checked by the compiler whereas C-style casts fail at runtime; in that regard, C++-style casts are definitely safer.
Neither is safer than the other. In both cases undefined behavior will occur should you modify the value through one of the pointers that have been casted. const_cast has the benefit of doing only what you want and expresses it clearly, while the C style cast could be everything and is not sensitive to the actual type of its argument.
It's safer, but in a different way than you imagine.
It's safer because you explicitly state you're casting away constness.
When someone sees your code, they think - "ok, here's a const_cast, this argument must have been const. Let's take a closer look at this", whereas a regular cast just gets lost in the back of the mind when reading big chunks of code.
I do not believe that it is possible to completely avoid C-style casts when writing C++. I was surprised to find out that I needed to use a C-style cast to avoid a compiler truncation warning:
short value_a = 0xF00D; // Truncation warning in VS2008
short value_b = static_cast<short>(0xF00D); // Truncation warning in VS2008
short value_c = (short)0xF00D; // No warning!
Are there other scenarios where there is no C++-style substitute for a C-style cast?
In C++, the C-style cast is defined (ยง5.4) in terms of C++-style casts. So for every cast you can do C-style, there's a matching C++-style cast (almost).
The "almost" is that C-style casts ignore base class accessibility. That is, there is no equivalent C++-style cast for the following:
struct foo {};
struct bar : private foo {};
bar b;
foo* f = (foo*)&b; // only way this can be done in a well-defined manner
So, no it's not strictly-speaking possible to completely ditch C-style casts. But the number of areas where a (combination of) C++-style casts doesn't suffice is few in count.
The above is the "language answer". What you're experiencing has nothing to do with C-style casts versus C++ casts, but just compiler implementation. Warnings are absolutely implementation-specific, and have nothing to do with C++.
So don't make the mistake of using your findings on this particular compiler in this particular situation for concluding things about C++ in general.
You are just trying to obfuscate your code, it is as simple as that. And the compiler is completely correct in telling you so.
If you have a precise idea what the assigned value should be, use that. My guess is that you have some unfounded presumption of short being 16 bit wide and that the sign representation of the target machine is two's complement. If that is so, assign -4083 to your variable. If you just need your variable as a bit vector, use an unsigned type.
As far as C is concerned the standard simply says about conversion from one integer type to another:
Otherwise, the new type is signed and
the value cannot be represented in it;
either the result is
implementation-defined or an
implementation-defined signal is
raised.
I imagine the the point of view of C++ with this respect is not much different. Other answers mention border cases where in C++ you would need a `C'-style cast to overrule all typechecks that C++ gives you. Feeling the need for them is an indication of bad design.
The case that you give as an example is certainly not one for which I would find any valid circumstances.
There are 4 c++ style casts, const_cast, reinterpret_cast, static_cast and dynamic_cast. They work as follows:
// const_cast casts away constness or adds it
const int const_integer = 5;
const_cast<int>(const_integer) = 3;
// static_cast will perform standards defined casts and will
// cast up or down a c++ inheritance hierarchy without checking the result of the cast
struct b {};
struct a : public b {};
struct c {};
double value = static_cast<double>(0.0f);
b* b_value = new b;
a* a_value = static_cast<a*>(b_value);
// dynamic_cast will perform any cast that static_cast will, but will check to see
// if the cast makes sense. If the values are not pointers, this cast can throw
b* value_b = new b;
a* value_a = new a;
b* new_b = dynamic_cast<b*>(value_a); // will return NULL
a* new_a = dynamic_cast<a*>(value_b); // will not return NULL
// reinterpret_cast will change any type to any other type, as long as the constness of the types is the same.
// the behavior of this cast is implementation specific.
double* a = new double;
*a = 0.0f;
int *b = reinterpret_cast<int*>(a);
A c-style cast in c++ simply tries to perform those casts in a specific order until one of them works. That order is as follows:
a const_cast
a static_cast
a static_cast followed by a const_cast
a reinterpret_cast, or
a reinterpret_cast followed by a const_cast.
So, in short, you can do any c-style cast in c++, because a c-style cast in c++ is just some arrangement of c++ style casts. Get it?
Yes, it is completely possible.
I never use C-style casts. I can write hundreds of thousands of lines of code without having to revert to using reinterpret_cast, C++'s closest cousin to the C-style cast. The only times I have to use reinterpret_cast is when doing socket programming -- a fairly narrow domain, in the big picture.
You don't need to use C-style casts, either. In your other post, you said
I could just use a negative value,
short my_value = -4083;
but in my code it is much more understandable to use hexadecimal.
So in this case you didn't have to use the cast. You chose to.
I was surprised to find out that I needed to use a C-style cast to avoid a compiler truncation warning
I see it the other way around: You use a C-style cast to prevent the compiler from warning you, and I see this as a severe disadvantage of the C-style cast.
if you feel you know what you're doing, then shut up the compiler for this one case by using a compiler-specific way. For example, for VC use something like
#pragma warning(push, disable: XXXX)
// code goes here
#pragma warning(pop)
In these cases, you can use reinterpret_cast. It was meant for a replacement of a unchecked C-style cast. The typical note here: this is unchecked cast, and should be avoided when possible by using the other available: const_cast, dynamic_cast, etc.