首页 > 解决方案 > 为什么 (const char*) ptr 不被视为左值

问题描述

我有以下代码(只有关键代码)和最少的示例代码,但由于行OFFSET_PTR(pFileBothDirInfo->NextEntryOffset, pFileBothDirInfo);(IDE错误:表达式必须是可修改的值。编译:错误C2106:'=':左操作数必须是左值.)

char packet_bytes[9] = {0};

int main(int argc, char* argv[]) {
    printf("(int)sizeof(smb2_query_directory_response_t) = %d\n", (int)sizeof(smb2_query_directory_response_t));
    printf("(int)sizeof(smb2_FileBothDirectoryInformation_t) = %d\n", (int)sizeof(smb2_FileBothDirectoryInformation_t));

    const smb2_query_directory_response_t*  pSMB2QueryDirectoryResponse = (smb2_query_directory_response_t*)packet_bytes;
    const smb2_FileBothDirectoryInformation_t *pFileBothDirInfo = pSMB2QueryDirectoryResponse->OutputBufferLength ? REINTERPRET_CAST(const smb2_FileBothDirectoryInformation_t*, pSMB2QueryDirectoryResponse->Buffer) : NULL;
    while (pFileBothDirInfo)
    {
        // ideone runs on linux with a compiler who consider wchar_t 4 bytes?
        // https://stackoverflow.com/questions/16944750/c-unicode-characters-printing
        //wprintf(L"%.*s|%.*s\n", pFileBothDirInfo->FileNameLength/2, pFileBothDirInfo->FileName, pFileBothDirInfo->ShortNameLength/2, pFileBothDirInfo->ShortName);
        if (pFileBothDirInfo->NextEntryOffset)
        {
            offset_ptr(pFileBothDirInfo->NextEntryOffset, pFileBothDirInfo);

            const unsigned char *ptrTemp;
            ptrTemp = ((const unsigned char*)pFileBothDirInfo + 10);
            //be equivalent to 
            //((const unsigned char*)pFileBothDirInfo) = ( (const unsigned char*)pFileBothDirInfo + 10 );
            OFFSET_PTR(pFileBothDirInfo->NextEntryOffset, pFileBothDirInfo);
            *((int *)10) = 100;
            printf("ptrTemp = %p", ptrTemp);
        } 
        else
        {
            break;
        }
    }
    return 0;
}

我还提到了L-Value 和 R-Value 表达式

左值具有您的程序可以访问的地址。左值表达式的示例包括变量名称,包括const变量、数组元素、返回左值引用的函数调用、位域、联合和类成员。

L-Value 和 R-Value Expressions,指出以下代码是合法的,但是 VS2015 IDE 及其编译器给了我一个错误。

char *p;
short i;
long l;

(long *)p = &l;     /* Legal cast   */
(long)i = l;        /* Illegal cast */

使用ideone编译器也有类似的错误:

Compilation error   #stdin compilation error #stdout 0s 15232KB
prog.cpp: In function ‘int main(int, char**)’:
prog.cpp:259:33: error: lvalue required as left operand of assignment
    OFFSET_PTR(pFileBothDirInfo->NextEntryOffset, pFileBothDirInfo);
                                 ^
prog.cpp:235:107: note: in definition of macro ‘OFFSET_PTR’
 #define OFFSET_PTR(byte_offset, ref_ptr) ((const unsigned char*)ref_ptr = (const unsigned char*)ref_ptr + byte_offset)

我认为(const unsigned char*)pFileBothDirInfo有一个地址,但为什么它不被视为左值?

参考

标签: c++visual-studio-2015

解决方案


我认为(const unsigned char*)pFileBothDirInfo有一个地址,但为什么它不被视为左值?

你想错了。

表达式 (T) cast-expression的结果是 T 类型。如果 T 是 [一个左值引用类型或一个对函数类型的右值引用],则结果是一个左值,如果 T 是 [一个对对象类型的右值引用],则结果是一个 xvalue ]; 否则结果是纯右值。

[expr.cast]([] 括号添加到组子句)

const unsigned char*不是任何类型的引用类型,因此结果是纯右值。

您正在创建一个 type 的值const unsigned char*。为什么它会与类型对象的存储相关联const smb2_FileBothDirectoryInformation_t *

MSVC 允许(long *)p = &l;作为扩展。


推荐阅读