I generally use LARGE_INTEGER data in order to increment of n bytes the overlapped structure. But how can I do it without using LARGE_INTEGER data type if, for example, I have to increment by 1000 bytes?
Asked
Active
Viewed 133 times
0
-
unfortunately `OVERLAPPED` very bad design in all sense. if you want be formal correct from *c++* view - you need copy `ULARGE_INTEGER ByteOffset = { ov.Offset, ov.OffsetHigh };` increment `ByteOffset.QuadPart += 0x1000;` and copy back - `ByteOffset.QuadPart += 0x1000;` however always correct will be do `(LONGLONG&)ov.Pointer += 0x1000;` - think about this way you ask. the best of course use direct `NtReadFile` and `NtWriteFile` – RbMm May 25 '20 at 10:13
-
1@rbm Reading the member of a union that is not the active member of a union is undefined behavior in C++. What you propose to be *"formal correct"* is in fact formally incorrect. – IInspectable May 25 '20 at 10:31
-
1@IInspectable: `OVERLAPPED` is hardly a portable type to start with. This is _de facto_ defined behavior for Visual C++. – MSalters May 25 '20 at 10:34
-
@msa With Visual Studio supporting clang-cl for a fair while now, portability indeed does matter. And with Clang being a fair bit more aggressive in face of undefined behavior, what used to be a hypothetical possibility has become a practical problem. – IInspectable May 25 '20 at 10:38
-
@IInspectable - really very good defined in windows subsystem. look for example to [LARGE_INTEGER](https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-large_integer~r1) and how it used. if personally you not want use this - not use. this is your right. – RbMm May 25 '20 at 11:02
-
@rbm It's a union, and unions have rules in C++ that are different from the rules for unions in C. Your claim that using a union in C++ in a way that's incorrect were *"formal correct"* is false. I'm not sure what point exactly you are trying to make. – IInspectable May 25 '20 at 11:06
-
@IInspectable - reread my first comment - for what i say "formal correct". false - is all what you write here. all – RbMm May 25 '20 at 11:08
-
@rbm Your proposed solution to make a copy sets the `LowPart` and `HighPart` members to be the active members of the union. You then move on to **read** `QuadPart`, an inactive member. Doing this in C++ exhibits undefined behavior. Introducing code that exhibits undefined behavior as *"formal correct"* is not living up to its promise. Sorry. – IInspectable May 25 '20 at 11:30
-
@IInspectable - i describe **2 different** solutions - and `(LONGLONG&)ov.Pointer += 0x1000;` is **second**. and it anyway will be correct and always working. the best of course how i write at begin at all use `NtReadFile` and `NtWriteFile` direct. – RbMm May 25 '20 at 11:34
-
@rbm Indeed. And the first 'solution' is introduced (let me repeat): *"if you want be formal correct from c++ view"*. You then move on to produce a 'solution', that isn't valid in C++. What else is there to say, really? – IInspectable May 25 '20 at 11:36
-
@IInspectable - *You then move on to read QuadPart, an inactive member.* - this is for what [`LARGE_INTEGER`](https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-large_integer~r1) union designed (and `ULARGE_INTEGER` too). – RbMm May 25 '20 at 11:36
-
@IInspectable - why is read "inactive" member UB ? always ? :) you want `QuadPart = ((ULONGLONG)OffsetHigh << 32) + Offset`. and `ByteOffset = { ov.Offset, ov.OffsetHigh };` can give **another** result ? really ?? – RbMm May 25 '20 at 11:40
-
@rbm *"why is read 'inactive' member UB ? always ?"* Because [such are the rules](https://stackoverflow.com/a/11996970/1889329). – IInspectable May 25 '20 at 12:07
-
@IInspectable - at first exist exceptions, for example [*One special guarantee is made in order to simplify the use of unions:*](http://eel.is/c++draft/class.union#2). but even it very narrow and bad formulated. but really question is more general - **why** ? i not agree with this and we can use and iactive members when we good understand what we doing – RbMm May 25 '20 at 12:12
-
and `[U]LARGE_INTEGER` special design for easy manipulate with low/hi/quad part. of course this is platform specific and assume 8 byte integer internal implementation – RbMm May 25 '20 at 12:16
-
@rbm *"at first exist exceptions"* - Those exceptions do not apply here. There is no *"common initial sequence"*. *"i not agree with this"* - The C++ Standard doesn't care about whether any given user agrees or disagrees with its rules. Compilers honor those rules and if you are using a compiler, you better get acquainted to those rules. *" we can use and iactive members when we good understand what we doing"* - If we understand, what we are doing, we do not access an inactive member of a union. *"`[U]LARGE_INTEGER` special design for easy manipulate"* - In C. Not in C++. – IInspectable May 25 '20 at 12:23
-
@IInspectable - yes, agree that The End. – RbMm May 25 '20 at 12:42
-
After all of this, is there any real answer to my question? – tiziocaio May 25 '20 at 14:51
-
@ninuz - variant #1 - `(LONGLONG&)ov.Pointer += ofs;` variant #2 `ULARGE_INTEGER ByteOffset = { ov.Offset, ov.OffsetHigh }; ByteOffset.QuadPart += ofs; ov.Offset = ByteOffset.LowPart, ov.OffsetHigh = ByteOffset.HighPart;` variant #3 - use `ByteOffset.QuadPart = ((ULONG64)ov.OffsetHigh << 32) + ov.Offset + ofs` variant #4 use `NtWriteFile` and `ZwReadFile` - so select by self – RbMm May 25 '20 at 14:57
1 Answers
0
DWORD64 offset = (((DWORD64)ov.OffsetHigh) << 32) | ov.Offset;
offset += 1000;
ov.OffsetHigh = (DWORD)(offset >> 32);
ov.Offset = (DWORD)offset;

Remy Lebeau
- 555,201
- 31
- 458
- 770
-
however `(LONGLONG&)ov.Pointer += 1000` will always work on any *c++* compiler with Little Endian. and even formal *c++* rules unrelated here because read from this will be done by external component – RbMm May 26 '20 at 07:01
-
@RbMm "*however `(LONGLONG&)ov.Pointer += 1000` will always work on any c++ compiler with Little Endian*" - it *may* "work", but it is relying of 2 implementation details that are not documented or consistent on all platforms. What you show is more *optimal* (when it works), but is less readable. What I showed is compliant and more readable. – Remy Lebeau May 26 '20 at 08:14
-
i think it not simply may work, but working and always will be work for any little endian platform – RbMm May 26 '20 at 08:24