Number Type Cast
-
@beecksche In C++ you should use static_cast and avoid C casts in general.
See https://www.quora.com/What-are-the-disadvantages-of-C-style-casting-in-C++ -
@J.Hilk you are right, it's
kind of constructorconstructor style cast. But it's C++ and less ugly than static_cast. Qt and me prefer this for primitive types, i.e. int, float etc.[Edit aha_1980: incorporated comments from kshegunov]
-
@aha_1980 said in Number Type Cast:
@J.Hilk you are right, it's kind of constructor.
There are no constructors for primitive types, thus it's no constructor. The "constructor-style cast", which is what you refer to, is of course the same as every other option performance-wise, so it's a matter of aesthetic preference.
-
@kshegunov Yeah, you're right, I didn't remember the exact name.
What I wanted to point out is, that this is C++ and has nothing to do with C casts.
-
@aha_1980 said in Number Type Cast:
What I wanted to point out is, that this is C++ and has nothing to do with C casts.
The constructor-style cast is completely equivalent to the C-style cast. It happily casts away
const
for example. So there's nothing special about it semantically. That is to say:Type2 x; Type1 y1 = (Type1) x; Type1 y2 = Type1(x);
are absolutely the same from the compiler's point of view.
-
@kshegunov said in Number Type Cast:
The constructor-style cast is completely equivalent to the C-style cast. It happily casts away
const
for example. So there's nothing special about it semantically.May I ask that you elaborate a bit more this statement above. It is not clear to me what you mean with "casts away"
Type2 x; Type1 y1 = (Type1) x;
MinGW and code model would complain with a warning for the statement above.
Type1 y2 = Type1(x);
MinGW and code model will not throw a warning at you.
Therefore I am using the last one.
-
@koahnig said in Number Type Cast:
May I ask that you elaborate a bit more this statement above. It is not clear to me what you mean with "casts away"
const void * x; int y = int(x);
compiles just fine.
static_cast
on the other hand should deny your stripping away theconst
qualifier. -
@koahnig
I'm surprised at what you say about MinGW warning for one and not the other. I've looked around the web and do not find anywhere mentioning possibly different compiler warning behaviour. I'd have expected to see it mentioned in e.g. https://stackoverflow.com/questions/4474933/what-exactly-is-or-was-the-purpose-of-c-function-style-casts or https://stackoverflow.com/questions/45505861/function-style-cast-vs-constructor. -
@kshegunov said in Number Type Cast:
const void * x; int y = int(x);
compiles just fine.
static_cast
on the other hand should deny your stripping away theconst
qualifier.actually no,
as int my be a smaller type than a pointer ;-)
But, of course with int64_t it works fine.But I'm nitpicking ..
Don't we have const_cast for the above mentioned cases ?
-
OK, I should have the "IIRC" there as I had before. Apparently current versions of MinGW do not.
Anyway, I tend to get rid of warnings as much as possible. Mainly because I left warnings in the far past and a missed warning caught me later on.
-
@J.Hilk said in Number Type Cast:
actually no,
Actually yes. Almost all errors that fall in the
-fpermissive
are there to prevent you from shooting yourself in the foot. The compiler can compile it just fine, hence the existence of the aforementioned flag. As a matter of fact if you try it with MSVC you're (probably with surprise) going to realize that it eats it just fine - no errors, just a warning or so.as int my be a smaller type than a pointer ;-)
So? Substitute
void *
withlong long
and see what happens ... pure magic ... Truncation is unimportant here, and truncation is not an error by the way.Don't we have const_cast for the above mentioned cases ?
Indeed, and some compilers may just allow you to
static_cast
it too depending on the types and how the compiler's implemented. However, here's a better snippet for your consideration:typedef void* voidp; const int * x; void * y = static_cast<voidp>(x); // Case 1 void * z = voidp(x); // Case 2
Case 1 is an error, because you're trying to
const_cast
andstatic_cast
at the same time, Case 2 is valid and compiles fine. Most of the time this is harmless, obviously, as with the case of primitive types, but, and I repeat again, there's no semantic difference between C-style casts and constructor-style casts; they are exactly the same thing. -
As I often need to code in several different languages I try to make my expressions as language agnostic as possible. Unless performance is a consideration I often do this to force a type conversion:
int a(12); int b(15); double d(a / (b + 0.0));
in many lanuages there will be an implicit conversion to floating point, and I prefer my conversion in the denominator.
-
@Kent-Dorfman This is a new one on me --- try to write code in one language so it will also work in another :)
-
-
Really interesting disucssion. I'm with @jsulm and use the "constructor-style cast" for primitives types.
int a = 10; double b = double(a);
And for safety reasons
*_cast
for classesMyBaseClass *base; MyDerivedClass *derived = static_cast<MyDerivedClass*>(base);
-
@beecksche I actually wrote that C style casts should be avoided in general (means: for all types including primitive types).
-
@beecksche said in Number Type Cast:
MyDerivedClass derived = static_cast<MyDerivedClass>(base);
Just one note: static_cast has absolutely no notion of safety. There's no check involved so you are completely responsible to ensure that the type you are casting to is really is valid with regard to the type you are casting from.
dynamic_cast
does check and in the case of pointers return a null pointer that you can validate before continuing your code. -