While debugging some of our code (C++) I found this:
inline std::string BufferToStr(
const unsigned char* buffer,
int index,
size_t length)
{
std::string retValue(reinterpret_cast<const char*>(&buffer[index], length));
return retValue;
}
The issue with this code (overlooking the lack of pointer and string length checks) is that the closing parenthesis of the reinterpret_cast
has been placed after length
when it should have been after &buffer[index]
. At first I thought that this was an issue with the compiler (using VS2013) but after successfully compiling it using both VS2012 and gcc 4.6.3, I've come to the conclusion that this is for some reason allowed. The code won't run on either Windows or Linux as the length parameter is used as the pointer.
So my question is why does this compile? Looking at the documentation of reinterpret_cast
I can't find any documentation on it saying that you can pass a comma separated list of values to it and what it will do with it.
reinterpret_cast is a type of casting operator used in C++. It is used to convert a pointer of some data type into a pointer of another data type, even if the data types before and after conversion are different. It does not check if the pointer type and data pointed by the pointer is same or not.
Although the reinterpret_cast itself might be unspecified behaviour, attempting to access the parameters once you've done the cast is undefined behaviour.
The reinterpret_cast allows the pointer to be treated as an integral type. The result is then bit-shifted and XORed with itself to produce a unique index (unique to a high degree of probability). The index is then truncated by a standard C-style cast to the return type of the function.
The reinterpret_cast operator performs potentially unsafe type casts. It is most often used to cast a pointer to a different pointer type. Casting a pointer to a different pointer and back is usually safe and yields the original value.
That is due to the comma operator in c/c++. The code(an expression):
(&buffer[index], length)
is equivalent to (&buffer[index] take no effect):
(length)
so your code is equivalent to:
inline std::string BufferToStr(const unsigned char* buffer, int index, size_t length)
{
std::string retValue(reinterpret_cast<const char*>(length));
return retValue;
}
reinterpret_cast
accepts an expression. What you have in the parenthesis is an expression - the "," operator with two sub-expressions, which will evaluate to the result of last sub-expression.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With