Is it safe initialize enum class reference with an integer? [duplicate] - c++

This question already has answers here:
Is it safe to reinterpret_cast an enum class variable to a reference of the underlying type?
(3 answers)
Using `reinterpret_cast` on an enum class - valid or undefined behavior?
(1 answer)
Closed 20 days ago.
given enum class Foo
enum class Foo : uint8_t
{
A, B, C
};
why does this cast fail?
uint8_t X = 1;
Foo& X_ref = *static_cast<Foo*>(&X);
but reinterpret cast does not fail?
uint8_t X = 1;
Foo& X_ref = *reinterpret_cast<Foo*>(&X);
I'm wondering if this cast is safe and I can safely assign enum values of Foo to X_ref and expect X to be changed accordingly as long as type of X is same as underlying type of enum class (in this case uint8_t)

Related

Is it UB to modify a const object's member via its non-const reference? [duplicate]

This question already has answers here:
C++ const object's member can be modified
(1 answer)
Why does C++ not have a const constructor?
(5 answers)
C++, Classes, Const, and strange syntax
(8 answers)
Closed 3 months ago.
class T {
public:
int v;
int &vRef;
public:
T() : v(0), vRef(v) {}
};
const T t; // note, it's a const object
t.vRef = 2;
printf("v: %d\n", t.v);
The code presented above compiles OK, and the const object's internal value did change.
Question. Is this Undefined Behavior or not?
Yes. If the object is declared as const, then modifying it (through any means, be that a non-const reference like in your example, via const_cast or something else) is UB.

Difference copy-initialization and direct-initialization for primitive (scalar) types [duplicate]

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.

static_cast<type>() vs type () [duplicate]

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.
}

C++ `int* class::*member = NULL` compiles, why? [duplicate]

This question already has answers here:
Pointer to class data member "::*"
(18 answers)
Closed 7 years ago.
I cannot figure out how this compiles. It seems like it should not, and if I use a value other than NULL in the constructor it will not.
#include <stdio.h>
class MyClass{
private:
int *first;
public:
MyClass();
};
MyClass::MyClass(){
int whatever = 42;
//int* MyClass::*first = &whatever;//This does not compile
int* MyClass::*first = NULL;//This compiles
}
int main(){
MyClass doSomething;
return 1;
}
It seems that generally the type Class::member = value syntax is used for static vars, which this is not.
Also, there is an asterisk before the member name, which confuses things even more.
If I switch the lines to the one that is commented out, the compiler complains, as expected.
error: cannot convert ‘int*’ to ‘int* MyClass::*’ in initialization
While I did expect an error, I have no idea what the type int* MyClass::* is. Or how it could be used.
This is a pointer to data member. You cannot initialize it with an ordinary pointer, that is why the commented out expression does not compile.

C++ class initialization with and without parentheses [duplicate]

This question already has answers here:
Do the parentheses after the type name make a difference with new?
(7 answers)
Closed 9 years ago.
What is the difference between the following 2 two initializations?
class Pod {
public:
int a, b;
};
Pod *p1 = new Pod;
Pod *p2 = new Pod();
In the first case the object is left uninitialized, while in the second case the object is guaranteed to be value-initialized, which in this case as the type is POD it means zero-initialized