我有以下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
有地址,但是为什么不将其视为左值?
参考
答案 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
项内容。就是这个意思。