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.
}
Related
This question already has answers here:
int a = 0 and int a(0) differences [duplicate]
(7 answers)
Closed 3 years ago.
as far as I understand in C++ is an initialization in the form
T x = a;
called copy-initialization and an initialization in the form
T x(a);
or
T x{a};
called direct-initialization.
(T...Type, x...variable name, a...expression)
For class types I think the difference is clear (calling copy constructor in case of copy-initialization).
But what if primitive (scalar) types like int are used? Because an int type has no (copy-)constructor which constructor should be called in case of
int x = 5; // copy-initialization
So is there a difference?
int x = 5; // copy-initialization of variable x
int x = {5}; // copy-initialization of variable x
int x(5); // direct-initialization of variable x
int x{5}; // direct-initialization of variable x
What happens here exactly? Or is there no difference if primitive/scalar types are involved and all is syntactic sugar. Similar questions doesnt explain that exactly for me.
There is no difference for primitive scalars like this; the memory location or register (depending on usage) is going to be initialized the same way.
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
This question already has answers here:
Default constructor with empty brackets
(9 answers)
Closed 8 years ago.
I recently wrote below simple program but compiler shows warning.
#include <iostream>
int main()
{
int a();
std::cout<<a;
return 0;
}
[Warning] the address of 'int a()' will always evaluate as 'true' [-Waddress]
What is the meaning of the above warning? Why value of a is 1 not 0?
It might look like a definition of a as an int, but:
int a();
declares a function a taking no parameters and return int.
Use:
int a{};
instead.
std::cout<<a;
calls operator<<() with bool which is always nonzero, hence true.
int a(); declares a function, not a variable. If you want a to be a zero-initialised variable, then you'll need one of
int a{}; // C++11 or later
int a = int();
int a(0);
int a = 0;
<< doesn't have an overload that can directly take a function; so it looks for a suitable conversion sequence to a type that it is overloaded for, and finds:
int() -> int(*)() -> bool
that is, using the standard function-to-pointer and pointer-to-boolean conversions. The function pointer won't be null, since a declared function must exist and have an address; so the boolean value will be true.
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.
Sometimes I need to learn the type of an expression while programming in C or C++. Sometimes there's a good IDE or existent documentation to help me, but sometimes not. I often feel such a construct could be useful:
void (*myFunc)(int);
printf("%s", nameoftype(myFunc)); //"void (*)(int)"
int i, unsigned int u;
printf("%s", nameoftype(i+u)); //"unsigned int"
This is especially true for C++; think accessors of const objects - do they return a const reference or a copy? Think dynamic casts and templated classes.
How can I do this? (i.e. learn the type of an expression)
I use GCC but as far as I know, it does not have such an extension. So I guess I'm curious as to how people solve this problem. (Both compile-time and runtime solutions welcome.)
Sometimes I just do:
int ***a = expression;
and look for the "<expression type> cannot be assigned to pointer-to^3 int" error. This seems to be the most portable workaround.
C++ has a typeid operator;
typeid(expression).name()
would return an implementation-defined name of the type of the expression. Alas, it is usually not human-readable.
What are you looking for? Automatic type inference or looking for the type so you can declare a variable correctly manually? (your own answers look like you want to have the second one). In this case, consider using Geordi:
<litb> make type pointer to function taking pointer to array of 10 int returning void
<geordi> void (*)(int (*)[10])
<litb> geordi: { int a = -1; unsigned int b = 0; cout << ETYPE(a + b), ETYPE_DESC(a + b), (a + b); }
<geordi> rvalue unsigned int, rvalue unsigned integer, 4294967295
<litb> geordi: << TYPE_DESC(void (*)(int (*)[10]))
<geordi> pointer to a function taking a pointer to an array of 10 integers and returning nothing
Automatic type inference is not currently possible without helper libraries like boost.typeof, which will use compiler extensions like __typeof__ for GCC. Next C++ will get auto (with different semantics than current auto) and will be able to do that, together with decltype to get the type of an expression.
If you can live with getting out of local context, you can always create a function template like this:
template<typename T> void f(T t) { /* ... */ }
int main() { int a = -1; unsigned int b = 0; f(a + b); }
Try Boost.Typeof to see if it fits.
gcc has typeof() at compile time. It works like sizeof().
http://gcc.gnu.org/onlinedocs/gcc/Typeof.html has more information.