There are a couple of questions with similar names on StackOverflow, such as this one and this one .etc
However, none of them answered the questions in my mind...
I'm including a C header file in C++ code. The problematic C code is shown below:
// C header file
static inline bool post_request(const customer_t *requester, const void *packagevoid)
{
const pkg_req_t *pkg = packagevoid;
...
... // some other code
}
The compiler complained that:
/<project_path>/handler_util.h:250:26: error: invalid conversion from 'const void*' to 'const const pkg_req_t*' {aka 'const pkg_req_s*'} [-fpermissive]
const pkg_req_t *pkg = packagevoid;
^~~~~~~
I changed the conversion to explictly use static_cast
:
// C header file: fixed
static inline bool post_request(const customer_t *requester, const void *packagevoid)
{
#ifdef __cplusplus
const pkg_req_t *pkg = static_cast<const pkg_req_t*>(packagevoid);
#else
const pkg_req_t *pkg = packagevoid;
#endif
...
... // some other code
}
const pkg_req_t *pkg = packagevoid;
--- why this is legal in C but giving error in C++? const_cast<pkg_req_t*>reinterpret_cast<const pkg_req_t*>
also works. Which one is better? why this is legal in C but giving error in C++?
In C++, implicit conversion from void*
to T*
is not allowed because it is not a "safe" conversion. Dereferencing the T*
would cause undefined behaviour unless the void*
actually did point to a T
object.
By the time C++ was created, it was too late to ban this type of implicit conversion in C because it would break all the code that does this:
T* p = malloc(sizeof(T)); // malloc returns void*
Therefore, it continues to be allowed in C.
Is static_cast an elegant solution in this case?
Yes, that's the "best practices" way to perform a conversion from const void*
to const T*
.
static_cast
is less dangerous than const_cast
and reinterpret_cast
, so it should be preferred over them. dynamic_cast
is less dangerous than static_cast
, but it cannot be used in this situation.
In the compilation error message, why is the compiler reporting "[-fpermissive]" in the end of the error message?
The compiler is telling you that if you compile your code with the -fpermissive
flag, it will accept the implicit conversion from const void*
to const T*
even though the standard does not allow it.