为什么 (const char*) ptr 不被视为左值

Why (const char*) ptr is not regarded as a lvalue

我有下面的code (only key code) and minimal example code,但是由于行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?
        // 
        //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 and R-Value Expressions

An lvalue has an address that your program can access. Examples of lvalue expressions include variable names, including const variables, array elements, function calls that return an lvalue reference, bit-fields, unions, and class members.

L-Value and 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 有一个地址,但为什么它不被视为左值?

参考资料

I think (const unsigned char*)pFileBothDirInfo has an address, but why it isn't considered as a lvalue?

你想错了。

The result of the expression (T) cast-expression is of type T. The result is an lvalue if T is [an lvalue reference type or an rvalue reference to function type] and an xvalue if T is [an rvalue reference to object type]; otherwise the result is a prvalue.

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

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

您正在创建 const unsigned char* 类型的值。为什么会关联到const smb2_FileBothDirectoryInformation_t *类型对象的存储?

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

OFFSET_PTR坏了。

是的,pFileBothDirInfo 有地址,但 (const unsigned char*)pFileBothDirInfo 是临时地址。一个右值。这就是对值类型执行强制转换时发生的情况!你得到一个新类型的新鲜对象。

另一个问题是const。您无法修改 const 项。就是这个意思。