unsigned long check_password(const char* p){
int* ip = (int*)p; // line 2, non-const not required
int i;
int res=0;
for(i=0; i<5; i++){
res += ip[i]; // line 6
}
return res;
}
Line 2 declares ip
as a pointer to integer and initializes it to (int*)p
. (int*)p
is a C-style cast, which is in this case resolved to reinterpret_cast<int*>(const_cast<char*>(p))
. See
When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?
ip
now points to the memory location of p. When using ip
, the memory at that location is interpreted as holding an integer, even though it holds a char; and it can be modified, even though it was initially declared const.
Line 6 treats ip
as if it was pointing to the first element of an array of int
and adds the i
th element of that array to res
. It's likely that ip
actually points to the first element of an array of char
. That means, that each iteration sizeof(int)
consecutive elements of that array are interpreted as the representation of a single int
.
The intention of this code is probably, that a sequence of 5 int
s is passed as an array of char
of length sizeof(int)*5
.
Note that this code is UB if p
doesn't actually point to memory of a size of at least sizeof(int)*5
, since the memory in that region is read. I.e. the char
-array must be at least of length sizeof(int)*5
.
Casting away the const in your code is not required
unsigned long check_password(const char* p){
const int* ip = reinterpret_cast<const int*>(p);
int res = 0;
for (int i = 0; i < 5; ++i){
res += ip[i];
}
return res;
}