Take a look at boost's Numeric Conversion library. I think you'll need to define an overflow policy that truncates the source value to the target's legal range (but I haven't tried it). In all, it may take more code than your example above, but should be more robust if your requirements change.
Answer from Pontus Gagge on Stack OverflowTake a look at boost's Numeric Conversion library. I think you'll need to define an overflow policy that truncates the source value to the target's legal range (but I haven't tried it). In all, it may take more code than your example above, but should be more robust if your requirements change.
Read Boost numeric_cast<> with a default value instead of an exception? So question.
You can use std::numeric_list as your default value when an exception is thrown
static cast - C++ static_cast - safer way. why? - Stack Overflow
Newest 'static-cast' Questions - Stack Overflow
c++ - How can I check whether a cast will result in overflow or underflow of the target type? - Stack Overflow
c++ - why does subtraction overflow with static_cast? - Stack Overflow
A static_cast is not safer than implicit conversion. However, you might have read that a static_cast is safer than a C cast. That's because it only allows "reasonable" casts. Some examples of a reasonable cast would be between numeric types, void * to some other pointer, base class ptr to derived class ptr. For example:
class Base {};
class D1 : public Base {};
class D11 {};
...
Base *ptr_to_Base(...); // Get from somewhere.
D11 *p = (D11 *) ptr_to_Base; // No compiler error! I need new eyeglasses!
D11 *p2 = static_cast<D11 *>(ptr_to_Base); // This gives you a compiler error.
Note that a static_cast can still allow bad casts, just not "unreasonable" ones:
class D2 : public Base {};
...
Base *b = new D2;
D1 *p3 = static_cast<D1 *>(b); // Wrong, but allowed by compiler.
In this case I'm prepared to suggest that the static_cast is not inherently safer. What the cast effectively does is tell the compiler to assume that the result will fit into the char and to not possibly warn you about data truncation. If you omit the cast, compilers are free to warn (especially if you request it) that data loss may be possible.
Not related to your question, but certainly related, static_cast is safer than both reinterpret_cast and C-style casts, because it has a much more limited set of legal conversions that it can perform.
When you do
static_cast<int>(s1.size()) - s2.size()
You convert s1.size() to a int and then when you subtract s2.size() from it that int is promoted to the same type as s2.size() and then it is subtracted. This means you still have unsigned integer subtraction and since that can't ever be negative it will wrap around to a larger number. It is no different from doing s1.size() - s2.size().
You have the same thing with
static_cast<int>(s1.size() - s2.size())
With the added bonus of possible signed integer overflow which is undefined behavior. You are still doing unsigned integer subtraction so if s1 is smaller than s2 than you wrap around to a large number.
What you need to do is convert both s1.size() and s2.size() to a signed integer type to get singed integer subtraction. That could look like
static_cast<ptrdiff_t>(s1.size()) - static_cast<ptrdiff_t>(s2.size())
And now you will actually get a negative number if s1.size() is less than s2.size().
It should be noted that all of this can be avoided by using less than operator. Your function can be rewritten to be
bool isShorter(const string &s1, const string &s2)
{
return s1.size() < s2.size();
}
which, IMHO, is much easier to read and understand.
Casting "one of them" to int leaves you with arithmetic operation that mixes string::size_type and int. In this mix the unsigned type has the same rank as int or higher, which means that the unsigned type still "wins": your int is implicitly converted back to string::size_type and the calculations are performed in the domain of string::size_type. Your conversion to int is effectively ignored.
Meanwhile, casting the result to int means that you are attempting to convert a value that does not fit into int's range. The behavior in such cases is implementation defined. In real-life 2's-complement implementations it is not unusual to see a simple truncation of the representation, which produces the "correct" result. This is not a good approach though.
If you want to perform this subtraction as a signed one, you have to convert both operands to signed types, making sure that the target signed type can represent both values.
(Theoretically, you can get away with converting just one operand to signed type, but for that you'd need to choose a type that can represent the entire range of string::size_type.)
There's gsl::narrow
narrow //
narrow<T>(x)isstatic_cast<T>(x)ifstatic_cast<T>(x) == xor it throwsnarrowing_error
You've got the use-case reversed.
The intended use of static_cast (and the other c++-style casts) is to indicate programmer intentions. When you write auto value = static_cast<int32_t>(value_64);, you're saying "Yes, I very much *intend* to downcast this value, possibly truncating it, when I perform this assignment". As a result, a compiler, which might have been inclined to complain about this conversion under normal circumstances (like if you'd have written int32_t value = value_64;) instead observes "well, the programmer has told me that this is what they intended; why would they lie to me?" and will silently compile the code.
If you want your C++ code to warn or throw an error on unsafe conversions, you need to explicitly not use static_cast, const_cast, reinterpret_cast, and let the compiler do its job. Compilers have flags that change how warnings are treated (downcasting int64_t to int32_t usually only results in a Warning), so make sure you're using the correct flags to force warnings to be treated as errors.
You must cast to function pointer types (not function types)
thread t1(static_cast<void (*)()>(&hello));
^^^
A function type (eg. void()) is a type that denotes a function by its parameters and return types. However there can be no variables of these types in the program (except function themselves, these are lvalues of function types). However, there can be references to functions or pointers to functions, of which you want to use the latter.
When you don't try to make variables (or temporary objects) of function type (eg. you typedef a function type, or use it as a template parameter), its use is OK. std::function<void()> only uses the parameter to specify its parameters and return type, so its designers decided to use this sleek syntax. Internally, it doesn't try to make variables with that type.
The standard determines that when taking the address of an overloaded function the use of that address can be used to disambiguate. That includes both assignment to a variable of the appropriate type or a cast.
What you are probably missing is that the type of &hello is not a function signature, but a function pointer, so the casts should be to void (*)() and/or void (*)(std::string).
void (*f)() = &hello; // target variable determines
// the correct overload
thread thr( (void(*)())&hello ); // or a cast (C or static_cast<>)
thread thr( static_cast<void(*)()>(&hello) );
First, understand that those lines are not equivalent.
int* anInt = (int*)aFloat; // is equivalent to
int* anInt = reinterpret_cast<int*>(aFloat);
What is happening here is that the programmer is asking the compiler to do whatever it can to make the cast.
The difference is important because using static_cast will only ask for a base type that is "safe" to convert to, where reinterpret_cast will convert to anything, possibly by just mapping the wanted memory layout over the memory of the given object.
So, as the "filter" is not the same, using a specific cast is more clear and safe than using the C cast. If you rely on the compiler (or runtime implementation if you use dynamic_cast) to tell you where you did something wrong, by avoid using C cast and reinterepret_cast.
Now that this is more clear, there is another thing: static_cast, reinterpret_cast, const_cast and dynamic_cast are easier to search for.
And the ultimate point: they are ugly. That's wanted. Potentially buggy code, code smells, obvious "tricks" that might generate bugs, are easier to track when it's associated with ugly look. Bad code should be ugly.
That's "by design". And that allows the developer to know where he could have done things better (by totally avoiding casts, if not really needed) and where it's fine but it's "documented" in the code by "marking" it as ugly.
A secondary reason for introducing the new-style cast was that C-style casts are very hard to spot in a program. For example, you can't conveniently search for casts using an ordinary editor or word processor. This near-invisibility of C-style casts is especially unfortunate because they are so potentially damaging. An ugly operation should have an ugly syntactic form. That observation was part of the reason for choosing the syntax for the new-style casts. A further reason was for the new-style casts to match the template notation, so that programmers can write their own casts, especially run-time checked casts.
Maybe, because static_cast is so ugly and so relatively hard to type, you're more likely to think twice before using one? That would be good, because casts really are mostly avoidable in modern C++.
Source: Bjarne Stroustrup (C++ creator)
C++ casts are more restrictive (so express your intent better and make code review easier, etc.). They're also much easier to search for, if you ever need to.
C style cast are faster to write and I prefer them when dealing with basic types. I find it annoying to write static_cast<double>(my_int) just so I can cast something to double for whatever the reason.
Are there any benefits of using statics_cast over C style cast for basic types?
It's possible to make that work, but not via overloading static_cast<>(). You do so by overloading the typecast operator:
class Square
{
public:
Square(int side) : side(side) {}
operator int() const { return side * side; } // overloaded typecast operator
private:
int side;
};
// ...
// Compiler calls Square::operator int() to convert aSquare into an int
cout << static_cast<int>(aSquare) <<endl;
Beware that overloaded typecast operators more often than not tend to do more harm than good. They make lots of nonsensical implicit cast operations possible. When you read this code snippet below, do you think "a is going to get the area of s"?
Square aSquare;
int a = aSquare; // What the heck does this do?
I certainly don't. This makes way more sense and is much more readable:
Square aSquare;
int a = aSquare.GetArea();
Not to mention that typically you want to be able to access other information about Square, like GetSide() or GetApothem() or GetPerimeter() or whatever. operator int() obviously can return only one int, and you can't have multiple operator int()s as members of a class.
Here's another situation where the operator int() makes code that compiles yet makes no sense whatsoever:
Square s;
if(s > 42) {} // Huh?!
What does it mean for a Square to be greater than 42? It's nonsense, but with the operator int() the code above will compile as Shape is now convertible to an int which can be compared to another int with a value 4.
So don't write typecast operators like that. In fact if you're overloading typecast operators you may want to think twice about what you're doing. There's actually only a few cases where overloading the typecast operator is useful in modern C++ (e.g. the safe bool idiom).
You can overload the cast operator:
struct square {
operator int() const {
return (side * side);
}
int side;
};
The only problem is that it will be used implicitly, and casting doesn't make much sense here. You also can't distinguish between the different types of casts (static_cast, c-style, etc)
This is the preferred way to do things:
struct square {
int get_area() const {
return (side * side);
}
int side;
}
If you must use a cast, use C++11 feature and mark it explicit. This prevents implicit casting mistakes.
This will do it:
#include <iostream>
using namespace std;
struct C{int n;};
struct A{int n;};
struct B : A, C{};
int main()
{
B b;
B* pb = &b;
cout << static_cast<C*>(pb) << "\n";
cout << reinterpret_cast<C*>(pb);
}
Note the differences in the two addresses.
I've built some multiple inheritance here, and have put an explicit member in the base classes, in order to circumvent possible optimisation of empty base classes to size zero.
See https://ideone.com/QLvBku
The simplest such case is reinterpret_cast<void*>(NULL), which may yield a non-null pointer.
By contrast, static_cast<void*>(NULL) is safe because it is required to yield a null pointer.
Why? NULL is an integer constant equal to 0. static_cast requires that 0 be converted to an appropriate null pointer, but reinterpret_cast does not have this same requirement. If the internal representation of a null pointer isn't the same as that of integer zero, then the results will be different. This type of breakage would be most likely on architectures with segmented addressing.