简体   繁体   中英

Why type casting of const void* is legal in C not C++ without using static_cast

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...

Problem Background:

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
}

Questions:

  1. const pkg_req_t *pkg = packagevoid; --- why this is legal in C but giving error in C++?
  2. Is static_cast an elegant solution in this case? --- I'm asking this question because it appears that const_cast<pkg_req_t*>reinterpret_cast<const pkg_req_t*> also works. Which one is better?
  3. In the compilation error message, why is the compiler reporting "[-fpermissive]" in the end of the error message?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM