Static_cast for const casts away qualifiers [duplicate] - c++

This question already has answers here:
What is the difference between const int*, const int * const, and int const *?
(23 answers)
Closed 3 years ago.
I'm writing a code with following function and new to C++
foo(void const *pCluster, const uint32_t fieldNum, __attribute__((unused)) const uint32_t subFieldNum, const int64_t value)
{
bool status = false;
mycustomStruct* const pFlmcCtrl = static_cast<mycustomStruct* const>(pMdbCluster);
// Some Processing
}
This gives error error: static_cast from 'const void *' to 'mycustomStruct* const' casts away qualifiers.
Please help me understand the error here. I could not understand

This
T const* p
is a pointer to a const T. This
T* const p
is a const pointer to a T. Notice the difference? In the first example, the thing the pointer points to is the thing that is const. In the second example, the pointer itself is the thing that is const. Attempting to cast a void const* to a mycustomStruct* const means casting a pointer that points to something that is const to a pointer that points to something that is not const (just the pointer itself happens to be const). Thus, this cast would drop a const qualifier, which is not something that static_cast can do…
You probably wanted to write
const mycustomStruct* pFlmcCtrl = static_cast<const mycustomStruct*>(pMdbCluster);

Related

Why can't I initialize a int* with the address of a const int [duplicate]

This question already has answers here:
What is the difference between const int*, const int * const, and int const *?
(23 answers)
Closed 6 years ago.
This is what I have:
const int x = 10;
int *ptr = &x; //error: 'initializing': cannot convert from 'const int *' to 'int *'
I know x can't be modified after initializing and I know how to fix this compilation problem, but why can't I use a pointer (in this case ptr) to point to x?
Although it is a const int, I don't understand the reason behind of why can't I point to it, as I can still use *ptr to represent x, right?
Because ptr is of type int*, i.e. it points to a non-const int. This allows you to modify ptr using *ptr. To prevent the const variable from being modified, the compiler prevents the initial assignment to a non-const pointer.
Making ptr point to a const int will naturally fix the problem: const int* ptr = &x;

What is the difference between declaring a string with const string and string const [duplicate]

This question already has answers here:
Const before or const after?
(9 answers)
Closed 9 years ago.
I'm browsing some code in the net, and I saw this two declaration,
const std::string strFoo = "MyFoo";
and
std::string const strBar = "MyBar";
I'm confused about the different placement of const keyword. What exactly its purpose?
Thanks!
In this case it makes no difference.
For more complicated declarations it may make a big difference.
You could say that const applies to what is to the left and if there's nothing there, it applies to what is to the right.
For example using const qualifier on a pointer to int:
const int* ptr1; // (1.) pointer to const int
int const * ptr2; // (2.) same as 1.
int* const ptr3; // (3.) const pointer to int
const int* const ptr4; // (4.) const pointer to const int
int const * const ptr4; // (5.) same as 4.
For more info on how to read complicated type declarations se this: C Right-Left Rule

What is meant by *const*a in c++

I am having a blocking trouble trying to figure out what it meant by the following 2 lines. following is a method declaration declared by gsoap and I am confused as to how I should define the parameters for the finstion
SOAP_FMAC3 void SOAP_FMAC4 **soap_serialize_PointerTomss__MobileUserType**(struct soap *soap, mss__MobileUserType *const*a)
So I am trying following but can not figure out what is the error here.
mss__MobileUserType const *mobile_user_type = setupMobileUsertype();
**soap_serialize_PointerTomss__MobileUserType**(soap , &mobile_user_type);
what am I doing wrong here.
Type *const* a;
a is a pointer to a const pointer to Type.
C++ const qualifier applies to what is left of it, if there is something on the left, otherwise it applies to what is on the right.
To make simpler consider this.
int a;
int* const p = &a; // (1)
int** pp = &p; // (2) This is not possible since `p` is `const` pointer.
int* const *ppc = &p; // (3) This is your case.
mss__MobileUserType* const mobile_user_type = setupMobileUsertype(); // (1)
mss__MobileUserType* const *mobile_user_type_p = &mobile_user_type; // (3)
soap_serialize_PointerTomss__MobileUserType(soap , mobile_user_type_p);
Read HERE and HERE for more about const correctness.
The function you are calling expects a pointer to const pointer
to (non-const) mss__MobileUserType. The expression
&mobile_user_type is a pointer to (non-const) pointer to const
mss__MobileUserType. There is no implicit conversion between
the two. (It's also strange to have a pointer to const pointer
to non-const, but I don't know the library, so perhaps there is
a reason. And it's also undefined behavior to have symbols with
two successive underscores.)
Assuming that your declaration is this:
SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_PointerTomss__MobileUserType(struct soap *soap, mss__MobileUserType *const *a);
Then you need to pass the address of a const pointer:
mss__MobileUserType *const mobile_user_type = setupMobileUsertype();
soap_serialize_PointerTomss__MobileUserType(soap , &mobile_user_type);
A declaration can start with a possibly cv-qualfied type-specifier, for example:
X
const X
X const
It can then be followed by zero of more ptr-declarators like:
*
* const
Each one specifies a pointer to the previous type. The const in the ptr-declarator applies to the pointer, not to the type:
For example:
const X*
X const*
X* const
X const * const
X const **const***
Let's break down:
const X ** const*
This is:
const X - const X
* - pointer to previous
* const - const pointer to previous
* - pointer to previous
So it is a "pointer to const pointer to pointer to const X"

How do I read C++ pointer construct?

This is a newbie C++ question. What is the difference between the following two constructs?
1. const int* const* const x
2. const int**
How do I read these constructs?
How do I read these constructs?
Read them backwards and read the * as "pointer to".
const int* const* const
is a constant pointer to a constant pointer to an integer constant.
const int**
is a pointer to a pointer to an integer constant.
It gets a bit easier if you group things the right way. For example, *const is really one unit meaning "const pointer to" (you can read the const as a subscript here: *const). I'd write it as:
const int *const *const p1; // p1 is a const pointer to const pointer to const int
const int **p2; // p2 is a pointer to pointer to const int
Also remember that declarations read "inside out", starting at the identifier being declared.
There is a tool that's useful/fun to decipher declarations: http://cdecl.ridiculousfish.com/
In your case it reports:
const int* const* const x => declare x as const pointer to const pointer to const int
const int** x => declare x as pointer to pointer to const int

C++ reinterpret_cast

I don't know why this simple code is not working:
int main()
{
const char* c = "ret";
typedef unsigned char GOK_UINT8;
typedef GOK_UINT8* pGOK_UINT8;
const pGOK_UINT8 y = reinterpret_cast<const GOK_UINT8*>(c);
return 0;
}
Can someone tell me why the reinterpret_cast does not work?
Can someone tell me why the reinterpret_cast should not work?
AFAICS, the reinterpret_cast should work fine, but the assignment afterwards should cause an error.
That's because a const GOK_UINT8* is a non-const pointer to const GOK_UINT8 objects, while a const pGOK_UINT8 is a const pointer to non-const objects.
The former protects the object referred to, the latter the pointer referring to the object. If the assignment would be allowed, you could then change the object that the const GOK_UINT8* meant to protect from changing.
Note that typedefed pointers behave strange that way. That's because of the strange declaration syntax of const in (C and thus also in) C++: A const protects the thing to its left, unless there isn't anything, then it protects the thing to its right. So in T const and in T const*, the object of type T is protected, while in T* const the pointer to an object of type T is protected. If you have
typedef T* TPtr;
then TPtr const again makes the pointer const. So does const TPtr. A typedefed pointer either points to const or non-const objects, you can't change that. You can't stuff a const into the vicinity of TPtr and expect that to protect the objects the pointer refers to.
(BTW, this is why STL classes have to define both an iterator and a const_iterator.)
Yep sbi is correct.
Modified your code accordingly,
const char* c = "ret";
typedef unsigned char GOK_UINT8;
typedef const GOK_UINT8* pGOK_UINT8;
pGOK_UINT8 y = reinterpret_cast<const GOK_UINT8*>(c);
printf("%s", y);