当转换void void指针时,Expression必须是指向完整对象类型的指针

时间:2017-07-26 07:54:44

标签: c

我正在尝试删除名称的扩展名是类型为wchar_t或char,在for()中我将void指针转换为类型为wchar_t或char,然后出现错误:

  

表达式必须是指向完整对象类型的指针。

以下是显示问题实例的示例代码。

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;
}

我不明白这个错误试图说的是什么。这里没有对象或结构。

2 个答案:

答案 0 :(得分:3)

要理解错误消息,您必须知道两件事:

  1. 在C中存储类型的任何值在C中称为对象。您的变量标识对象,指针(应该)指向对象。
  2. C中的类型可以是完整的或不完整的。区别在于对于完整的类型,该类型的对象的大小是已知的。对于不完整的类型,它是未知的。不知道大小,例如索引是不可能的,因为您需要大小来计算下一个数组元素的偏移量。 void不完整类型的特例:它无法完成,因为它未知(void *泛型指针类型并且可能指向任何类型的对象)。
  3. 因此,您的编译器只是告诉您p_str[ii]无效,因为您尝试索引void *类型的指针。

    问题的根源很简单:索引的优先级高于强制转换,因此只需使用parantheses来解决此问题:

    ((wchar_t *)p_str)[ii]
    

答案 1 :(得分:1)

我不知道为什么你会得到那个错误,但根据this表 表达

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

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

可能它不是你想要的