2017-07-26 45 views
1

我想要做的功能刪除擴展的名稱是類型wchar_t或字符,裏面的()我投射void指針類型wchar_t或字符,然後出現錯誤:表達式必須是一個指向一個完整的對象類型時投射void pointer

Expression must be a pointer to a complete object type.

以下是用於顯示問題實例本身的示例代碼。

int RemoveExtension(
    void *p_str,  /* Name      */ 
    bool isWchar  /* true:wchar_t, false:char */ 
) { 
    int ii, len; 

    // Get length 
    len = (isWchar) ? wcslen((wchar_t *)p_str) : strlen((char *)p_str); 

    // Remove extension 
    /* wchar_t */ 
    if(isWchar) { 

     for(ii = 0; ii < len; ii++) { 
      if(L'.' == (wchar_t *)p_str[ii]) { //Error here 
       (wchar_t *)p_str[ii] = L'\0';  //Error here 
       break; 
      } 
     } 
    } 
    /* char */ 
    else { 

     for(ii = 0; ii < len; ii++) { 
      if('.' == (char *)p_str[ii]) {  //Error here 
       (char *)p_str[ii] = '\0';   //Error here 
       break; 
      } 
     } 
    } 

    return 0; 
} 

我不明白這個錯誤想說什麼。這裏沒有對象或結構。

+1

'(wchar_t的*)p_str [II]' - > '((wchar_t *)p_str)[ii]' - 參見http://en.cppreference.com/w/c/language/operator_precedence –

+1

「*這裏沒有對象或結構。*」< - 有。無論你的'void *'指向的是C中的*對象*。但'void'是一個不完整的類型,所以你的編譯器不知道它的大小,因此不能進行索引。索引的優先級高於演員。首先使用派生類型轉換爲完整類型,然後編制索引。 –

+0

@FelixPalmen:我明白。非常感謝你。究竟!!! – Oosutsuke

回答

1

我不知道爲什麼你得到完全的錯誤,但根據this表 表達

(wchar_t *)p_str[ii](wchar_t *)(p_str[ii])

((wchar_t *)p_str)[ii]

可能不是你想要什麼

+0

我明白了。非常感謝你。 +1 – Oosutsuke

2

要了解錯誤信息,你必須知道兩件事:

  1. C中存儲的類型的任何值在C中都被稱爲對象。變量標識對象,指針(應指向)對象。
  2. C中的類型可以是完整的或不完整的。區別在於,對於完整的類型,該類型的對象的大小是已知的。對於不完整的類型,它是未知的。不知道大小,例如索引是不可能的,因爲你需要大小來計算下一個數組元素的偏移量。 void不完全類型的一種特殊情況:它永遠不能完成,因爲它是未知的(void *通用指針類型並可能指向的任何類型的對象)。

所以,你的編譯器只是告訴你,p_str[ii]是無效的,因爲你試圖指數void *類型的指針。


問題的來源是簡單的:索引具有比鑄造的優先級高,因此只需使用括號來解決這個問題:

((wchar_t *)p_str)[ii] 
+0

謝謝您的明確解釋! +1 – Oosutsuke

相關問題