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

时间:2019-06-03 11:03:47

标签: c++ visual-studio-2015

我有以下code(仅键代码)和minimal example code,但是由于行OFFSET_PTR(pFileBothDirInfo->NextEntryOffset, pFileBothDirInfo);是非法的(IDE错误:expression必须是可修改的值。编译:错误C2106:“ =”:左操作数必须为L值。)

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 and R-Value Expressions

  

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

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有地址,但是为什么不将其视为左值?

参考

2 个答案:

答案 0 :(得分:2)

  

我认为const unsigned char*有地址,但是为什么不将其视为左值?

您认为错了。

  

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

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

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

您正在创建类型const smb2_FileBothDirectoryInformation_t *的值。为什么将它与类型为(long *)p = &l;的对象的存储相关联?

MSVC允许var builder = services.AddMvc(); builder.AddJsonOptions(options => { options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; // for UTC for datetime options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc; IsoDateTimeConverter dateConverter = new IsoDateTimeConverter { DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.fff'Z'" }; //options.SerializerSettings.Converters.Add(dateConverter); }); 作为扩展名。

答案 1 :(得分:1)

OFFSET_PTR已损坏。

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

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