簡體   English   中英

為什么在不使用 static_cast 的情況下,const void* 的類型轉換在 C 而非 C++ 中是合法的

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

StackOverflow 上有幾個名稱相似的問題,例如this onethis one .etc

然而,他們都沒有回答我心中的問題……

問題背景:

我在 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
}

問題:

  1. const pkg_req_t *pkg = packagevoid; --- 為什么這在 C 中是合法的,但在 C++ 中給出錯誤?
  2. 在這種情況下,static_cast 是一個優雅的解決方案嗎? --- 我問這個問題是因為const_cast<pkg_req_t*>reinterpret_cast<const pkg_req_t*>也有效。 哪一個更好?
  3. 在編譯錯誤信息中,為什么編譯器會在錯誤信息的末尾報告“[-fpermissive]”?

為什么這在 C 中是合法的,但在 C++ 中會出錯?

在 C++ 中,從void*T*隱式轉換是不允許的,因為它不是“安全”的轉換。 void*引用T*會導致未定義的行為,除非void*實際上確實指向T對象。

到 C++ 被創建時,在 C 中禁止這種類型的隱式轉換為時已晚,因為它會破壞所有執行此操作的代碼:

T* p = malloc(sizeof(T));  // malloc returns void*

因此,它在 C 中繼續被允許。

在這種情況下,static_cast 是一個優雅的解決方案嗎?

是的,這是執行從const void*const T*轉換的“最佳實踐”方式。

static_castconst_castreinterpret_cast危險性小,因此應該優先於它們。 dynamic_caststatic_cast危險性小,但不能在這種情況下使用。

在編譯錯誤信息中,為什么編譯器會在錯誤信息的末尾報告“[-fpermissive]”?

編譯器告訴您,如果您使用-fpermissive標志編譯代碼,它會接受從const void*const T*的隱式轉換,即使標准不允許這樣做。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM