My aim is to keep intact value of pValueData which is being passed as
const char*
That's impossible. Passing via const means it cannot be modified, except when it was originally not constant.
Example:
char *ptr1 = new char[100]; // not const
char *ptr2 = new char[100]; // not const
int i = FunctionName(ptr1, ptr2, 123);
In this case, you could technically keep the const_cast. But what for? Just change your function parameters to take char *:
int FunctionName(char *pValueName, char *pValueData, long iMaxValueSize)
{
int iActualSiz = ProcessData(pValueData, iMaxValueSize);
// ...
}
However, you most likely want to be able to pass constant strings. For example string literals:
int i = FunctionName("name", "data", 123);
String literals are unmodifiable and thus require your function to take char const *. A later attempt to modify them causes undefined behaviour.
As you can see, the error is in the general architecture and code logic. You want to modify something and at the same time you do not want to allow to modify it.
The question is: What happens with your pDataToStore when ProcessData is done with it? Does the caller of FunctionName need to be aware of the modifications? Or is it just internal business of FunctionName?
If it's just internal business of FunctionName, then you can keep its signature intact and have ProcessData modify a copy of the passed data. Here is a simplified (not exception-safe, no error checks) example:
int FunctionName(const char *pValueName, const char *pValueData, long iMaxValueSize)
{
char *copy = new char[strlen(pValueData) + 1];
strcpy(copy, pValueData):
int iActualSiz = ProcessData(copy, iMaxValueSize);
// ...
delete[] copy;
}
The nice thing is that you can now massively improve the interface of FunctionName by hiding all the low-level pointer business. In fact, why use so many pointers at all when C++ standard classes can do all the work for you?
int FunctionName(std::string const &valueName, std::string const &valueData, long maxValueSize)
{
std::vector<char> copy(valueData.begin(), valueData.end());
int actualSize = ProcessData(©[0], maxValueSize);
// ...
// no more delete[] needed here
}
The std::vector<char> automatically allocates enough memory to hold a copy of valueData, and performs the copy. It fully automatically frees the memory when it is no longer needed, even if exceptions are thrown. And ©[0] (which in C++11 can be written as copy.data()) is guaranteed to yield a pointer to the internally used data, so that low-level C functions can modify the vector's elements.
(I've also taken the chance to remove the Microsoft-style Hungarian Notation. It's a failed experiment from the 90s, and you've even used it incorrectly, supposing that a leading i is supposed to indicate an int.)
The bottom line is really:
If you need a const_cast anywhere in your code to make it compile, then somewhere else there is at least either one const missing or one too much. A const_cast always makes up for a mistake in another piece of code. It is always a workaround and never a solution designed up front.