为什么在不使用 static_cast 的情况下,const void* 的类型转换在 C 而不是 C++ 中是合法的
Why type casting of const void* is legal in C not C++ without using static_cast
Whosebug 上有几个名称相似的问题,例如 and this one .etc
然而,none 回答了我心中的问题...
问题背景:
我在 C++ 代码中包含了一个 C 头文件。有问题的C代码如下所示:
// C header file
static inline bool post_request(const customer_t *requester, const void *packagevoid)
{
const pkg_req_t *pkg = packagevoid;
...
... // some other code
}
编译器抱怨:
/<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;
^~~~~~~
我将转换更改为明确使用 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;
--- 为什么这在 C 中是合法的,但在 C++ 中却给出错误?
- 在这种情况下 static_cast 是一个优雅的解决方案吗? --- 我问这个问题是因为
const_cast<pkg_req_t*>reinterpret_cast<const pkg_req_t*>
似乎也有效。哪一个更好?
- 在编译错误信息中,为什么编译器在错误信息的最后报“[-fpermissive]”?
why this is legal in C but giving error in C++?
在 C++ 中,不允许从 void*
到 T*
的隐式转换,因为它不是 "safe" 转换。取消引用 T*
会导致未定义的行为,除非 void*
实际上确实指向 T
对象。
在创建 C++ 时,在 C 中禁止这种类型的隐式转换为时已晚,因为它会破坏执行此操作的所有代码:
T* p = malloc(sizeof(T)); // malloc returns void*
因此,它在 C 中继续被允许。
Is static_cast an elegant solution in this case?
是的,这就是 "best practices" 执行从 const void*
到 const T*
的转换的方法。
static_cast
比 const_cast
和 reinterpret_cast
危险性小,因此应该优先于它们。 dynamic_cast
比 static_cast
危险性小,但不能在这种情况下使用。
In the compilation error message, why is the compiler reporting "[-fpermissive]" in the end of the error message?
编译器告诉您,如果您使用 -fpermissive
标志编译代码,它将接受从 const void*
到 const T*
的隐式转换,即使标准不允许它。
Whosebug 上有几个名称相似的问题,例如
然而,none 回答了我心中的问题...
问题背景:
我在 C++ 代码中包含了一个 C 头文件。有问题的C代码如下所示:
// C header file
static inline bool post_request(const customer_t *requester, const void *packagevoid)
{
const pkg_req_t *pkg = packagevoid;
...
... // some other code
}
编译器抱怨:
/<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;
^~~~~~~
我将转换更改为明确使用 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;
--- 为什么这在 C 中是合法的,但在 C++ 中却给出错误?- 在这种情况下 static_cast 是一个优雅的解决方案吗? --- 我问这个问题是因为
const_cast<pkg_req_t*>reinterpret_cast<const pkg_req_t*>
似乎也有效。哪一个更好? - 在编译错误信息中,为什么编译器在错误信息的最后报“[-fpermissive]”?
why this is legal in C but giving error in C++?
在 C++ 中,不允许从 void*
到 T*
的隐式转换,因为它不是 "safe" 转换。取消引用 T*
会导致未定义的行为,除非 void*
实际上确实指向 T
对象。
在创建 C++ 时,在 C 中禁止这种类型的隐式转换为时已晚,因为它会破坏执行此操作的所有代码:
T* p = malloc(sizeof(T)); // malloc returns void*
因此,它在 C 中继续被允许。
Is static_cast an elegant solution in this case?
是的,这就是 "best practices" 执行从 const void*
到 const T*
的转换的方法。
static_cast
比 const_cast
和 reinterpret_cast
危险性小,因此应该优先于它们。 dynamic_cast
比 static_cast
危险性小,但不能在这种情况下使用。
In the compilation error message, why is the compiler reporting "[-fpermissive]" in the end of the error message?
编译器告诉您,如果您使用 -fpermissive
标志编译代码,它将接受从 const void*
到 const T*
的隐式转换,即使标准不允许它。