I have the following code (only key code) and minimal example code, but it is illegal because of the line OFFSET_PTR(pFileBothDirInfo->NextEntryOffset, pFileBothDirInfo);
(IDE error: expression must be a modifiable value. Compile: error C2106: '=': left operand must be l-value.)
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://stackguides.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;
}
I also referred to 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.
and L-Value and R-Value Expressions, which points out that the following code is legal, but The VS2015 IDE and its compiler gave me an error.
char *p;
short i;
long l;
(long *)p = &l; /* Legal cast */
(long)i = l; /* Illegal cast */
It has a similar error using ideone compiler:
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)
I think (const unsigned char*)pFileBothDirInfo
has an address, but why it isn't considered as a lvalue?
References
- Quick Q: What are rvalues, lvalues, xvalues, glvalues, and prvalues?
- C++ International Standard (Working Draft, Standard for Programming Language C++ n4618.pdf)
- Value categories
- Bjarne Stroustrup's explanation: “New” Value Terminology
- L-Value and R-Value Expressions
- Lvalues and Rvalues (C++)
- What are rvalues, lvalues, xvalues, glvalues, and prvalues?
- L value vs R value in C
- What is lvalue and rvalue in C?
- lvalue and rvalue in C language
- Lvalues and rvalues
- 3.10 Lvalues and rvalues [basic.lval]
- 3.10 Lvalues and rvalues
printf
format specifier for the typesize_t
(which is returned bysizeof
):"%zu"
. Or just usestd::cout
and the overloaded<<
operator. – Some programmer dude*((int *)10) = 100;
What the hell is this? – Daniel Langr