2

There is the ULARGE_INTEGER union for compilers that don't support 64 bit arithmetic.

What would happen in the following code if the addition on the last line overflows?

ULARGE_INTEGER u;
u.LowPart = ft->dwLowDateTime;
u.HighPart = ft->dwHighDateTime;
u.LowPart += 10000; //what if overflow?

Related question: What is the point of the ULARGE_INTEGER union?

Roland
  • 7,525
  • 13
  • 61
  • 124

1 Answers1

8

ULARGE_INTEGER is composed of two unsigned values. Unsigned values are guaranteed to wrap round, so in some sense they can't "overflow".

If wrap round does occur, u.LowPart will end up being less than 10,000. What you probably want is:

u.LowPart += 10000;
if (u.LowPart < 10000) u.HighPart++;

... but what compiler still doesn't support 64-bit integers these days? They have been required by the C++ standard since 2011, and the C standard since 1999. So what you really want is:

u.QuadPart += 10000;  // Forget about legacy compilers that doen't support 64 bits.
  • Understood. I'm just trying to understand how `ULARGE_INTEGER` is to be used if you only have 32 bit arithmetic. So you have to check for overflow and increment the `HighPart` as you did in your code fragment? – Roland Aug 07 '17 at 05:56
  • 1
    @Roland : Yup. Similarly if you are trying to emulate 1024 bit arithmetic with 64 bit values. – Martin Bonner supports Monica Aug 07 '17 at 05:57
  • Then the following linked reply is actually incorrect, since it says that I could just perform addition on the `QuadPart` on a 32 bit compiler https://stackoverflow.com/a/14932949/480894 – Roland Aug 07 '17 at 06:09
  • @Roland: why do you think it is incorrect? 32 bit compilers provide 64 bit arithmetic since ages, exactly as compilers for 16 bit platforms provide arithmetic on 32 (or even 64) bit types. – Matteo Italia Aug 07 '17 at 06:11
  • @MatteoItalia I understood that `ULARGE_INTEGER` was intended to be used on compilers that *don't* support 64 bit arithmetic. Is this assumption incorrect? – Roland Aug 07 '17 at 06:25
  • It's correct, I'm just saying that virtually all 32 bit compilers targeting Windows in the last 15+ years do support 64 bit arithmetic - of course operations on 64 bit types aren't compiled to single instructions (and most complex ones, such as divisions, are typically translated in a call to a division function provided by the C runtime), but at least you don't have to explicitly worry about implementing them. That's why I say that the linked answer is correct even for 32 bit compilers - unless of course you have a truly ancient one (but then it should be explicitly stated in the question). – Matteo Italia Aug 07 '17 at 06:31
  • For example, [here](https://msdn.microsoft.com/en-us/library/aa261215(v=vs.60).aspx) you can see that it was supported un VC++ 6 - that's almost 20 years ago! – Matteo Italia Aug 07 '17 at 06:36
  • 1
    @MatteoItalia I got it. `uli.QuadPart += 10000;` will only work if your compiler supports 64 bit arithmetic, otherwise you have to check for overflow as in Martin Bonner's code. – Roland Aug 07 '17 at 06:40
  • 1
    I still work with a C cross compiler on a 16 bit microprocessor, and I'm fine. – Tom Kuschel Aug 07 '17 at 06:45
  • 1
    Without long long (64) , and I'm fine. ANSI X3.159-1989 standard [ANSI] – Tom Kuschel Aug 07 '17 at 06:52
  • @TomKuschel: good for you, but here we are talking about 32 bit compilers targeting Win32. The problems, the tools and the general environment are different. – Matteo Italia Aug 07 '17 at 07:51
  • @Roland: exactly, which means that, given the widespread availability of built-in 64 bit arithmetic, this particular instance of this pattern is mostly an historical artifact. – Matteo Italia Aug 07 '17 at 07:53