digitalmars.D - Pop Quiz what is wrong with this code?
- Danni Coy (11/11) Jun 20 2020 ...
- rikki cattermole (3/16) Jun 20 2020 oo oo, is it that you didn't want x and y to be of type size_t?
- Danni Coy (7/23) Jun 20 2020 more specifically I didn't want them to be unsigned
- rikki cattermole (11/36) Jun 20 2020 You are performing an operation on memory, size_t is indeed what you
- Danni Coy (11/41) Jun 20 2020 I am working with slices rather than with pointers directly.
- Steven Schveighoffer (7/8) Jun 20 2020 foreach(ptrdiff_t y, ref row; offsetMap)
- Avrina (4/13) Jun 20 2020 Why isn't that deprecated as well? implicitly converting from
- Danni Coy (19/37) Jun 20 2020 It turns out this line is the bigger problem.
- Steven Schveighoffer (6/41) Jun 22 2020 So this entire conversation is incorrect -- there is no promotion to
- WebFreak001 (15/59) Jun 22 2020 I think the issue is that it's converting the ulongs to float,
- Steven Schveighoffer (6/67) Jun 22 2020 But the OP rejected the idea of using ptrdiff_t (or did he?), which
- Kagamin (5/10) Jun 22 2020 OP is precise:
- Steven Schveighoffer (7/20) Jun 22 2020 That is exactly what declaring the variables to be ptrdiff_t would do.
- Patrick Schluter (3/21) Jun 21 2020 No. conversion of ulong to uint loses 32 times more data than
- Avrina (6/28) Jun 21 2020 Lol, it's not linear friend.
- Avrina (2/31) Jun 21 2020 Not that it should matter how much, it's a problem either way.
- Patrick Schluter (8/38) Jun 21 2020 But a much less severe one.
- Avrina (11/53) Jun 21 2020 That's an index to an array, not a file. The File api uses ulong
- Steven Schveighoffer (6/22) Jun 22 2020 It's not an error as you don't lose information.
... foreach (y, ref row; offsetMap) { auto run = 0; auto nPixels = 0; foreach (x; 0..size.x) { immutable SDL_FPair offset = { center.x - x, y - center.y }; ... and why does it violate the principle of making the right thing the easy thing to do?
Jun 20 2020
On 21/06/2020 3:08 AM, Danni Coy wrote:... foreach (y, ref row; offsetMap) { auto run = 0; auto nPixels = 0; foreach (x; 0..size.x) { immutable SDL_FPair offset = { center.x - x, y - center.y }; ... and why does it violate the principle of making the right thing the easy thing to do?oo oo, is it that you didn't want x and y to be of type size_t? And why are you initializing run and nPixels manually?
Jun 20 2020
On Sun, Jun 21, 2020 at 1:15 AM rikki cattermole via Digitalmars-d <digitalmars-d puremagic.com> wrote:On 21/06/2020 3:08 AM, Danni Coy wrote:more specifically I didn't want them to be unsigned I am adapting the code from C++ code, coming from other Algol syntax languages. That one is a real gotcha. I tried explicitly making x and y ints and I got a depreciation warning.... foreach (y, ref row; offsetMap) { auto run = 0; auto nPixels = 0; foreach (x; 0..size.x) { immutable SDL_FPair offset = { center.x - x, y - center.y }; ... and why does it violate the principle of making the right thing the easy thing to do?oo oo, is it that you didn't want x and y to be of type size_t?And why are you initializing run and nPixels manually?the value there so the compiler can figure out the type (auto)
Jun 20 2020
On 21/06/2020 4:00 AM, Danni Coy wrote:On Sun, Jun 21, 2020 at 1:15 AM rikki cattermole via Digitalmars-d <digitalmars-d puremagic.com> wrote:You are performing an operation on memory, size_t is indeed what you wanted. It is an offset into the address space past another offset (the pointer). You cannot fit the entire address space into an int, but a size_t value is guaranteed to be able to do this. Hence size_t is the correct data type for indexes over a slice.On 21/06/2020 3:08 AM, Danni Coy wrote:more specifically I didn't want them to be unsigned I am adapting the code from C++ code, coming from other Algol syntax languages. That one is a real gotcha. I tried explicitly making x and y ints and I got a depreciation warning.... foreach (y, ref row; offsetMap) { auto run = 0; auto nPixels = 0; foreach (x; 0..size.x) { immutable SDL_FPair offset = { center.x - x, y - center.y }; ... and why does it violate the principle of making the right thing the easy thing to do?oo oo, is it that you didn't want x and y to be of type size_t?You don't need to do this. All D types are default initialized to a value. int in this case will default initialize to 0, which is what you are doing explicitly.And why are you initializing run and nPixels manually?the value there so the compiler can figure out the type (auto)
Jun 20 2020
On Sun, Jun 21, 2020 at 2:25 AM rikki cattermole via Digitalmars-d <digitalmars-d puremagic.com> wrote:On 21/06/2020 4:00 AM, Danni Coy wrote:I am working with slices rather than with pointers directly. In this case the maximum size of x or y I could possibly imagine being useful is less than 64,000 realistic sizes for what I am doing are in the 10s or 100s. This might not be the part I am most worried about.On Sun, Jun 21, 2020 at 1:15 AM rikki cattermole via Digitalmars-d <digitalmars-d puremagic.com> wrote:You are performing an operation on memory, size_t is indeed what you wanted. It is an offset into the address space past another offset (the pointer).On 21/06/2020 3:08 AM, Danni Coy wrote:more specifically I didn't want them to be unsigned I am adapting the code from C++ code, coming from other Algol syntax languages. That one is a real gotcha. I tried explicitly making x and y ints and I got a depreciation warning.... foreach (y, ref row; offsetMap) { auto run = 0; auto nPixels = 0; foreach (x; 0..size.x) { immutable SDL_FPair offset = { center.x - x, y - center.y }; ... and why does it violate the principle of making the right thing the easy thing to do?oo oo, is it that you didn't want x and y to be of type size_t?All D types are default initialized to a value. int in this case will default initialize to 0, which is what you are doing explicitly.I can do int nPixels; or auto nPixels = 0;
Jun 20 2020
On 6/20/20 12:00 PM, Danni Coy wrote:I tried explicitly making x and y ints and I got a depreciation warning.foreach(ptrdiff_t y, ref row; offsetMap) is that what you wanted? ptrdiff_t is the signed version of size_t. The complaint is not that you are converting from unsigned to signed, but that you are converting from 64-bit to 32-bit. -Steve
Jun 20 2020
On Saturday, 20 June 2020 at 18:15:27 UTC, Steven Schveighoffer wrote:On 6/20/20 12:00 PM, Danni Coy wrote:Why isn't that deprecated as well? implicitly converting from ulong to long is an error as much as ulong to uint.I tried explicitly making x and y ints and I got a depreciation warning.foreach(ptrdiff_t y, ref row; offsetMap) is that what you wanted? ptrdiff_t is the signed version of size_t. The complaint is not that you are converting from unsigned to signed, but that you are converting from 64-bit to 32-bit. -Steve
Jun 20 2020
On Sun, Jun 21, 2020 at 9:40 AM Avrina via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Saturday, 20 June 2020 at 18:15:27 UTC, Steven Schveighoffer wrote:It turns out this line is the bigger problem. immutable SDL_FPair offset = { center.x - x, y - center.y }; FPair is a struct SDL_FPair { float x; float y; ... if those values were ints. dmd will not allow a downcast from ulong to int (the compiler would have caught the issue for me) but it will allow casting ulong to float which is why It took me a couple of hours with a debugger trying to find the bug. So this turns out to be more of a corner case than I thought. offset is a pair of floats because it's about to used in a bunch of angle calculations and I wanted to minimise the number of casts.On 6/20/20 12:00 PM, Danni Coy wrote:Why isn't that deprecated as well? implicitly converting from ulong to long is an error as much as ulong to uint.I tried explicitly making x and y ints and I got a depreciation warning.foreach(ptrdiff_t y, ref row; offsetMap) is that what you wanted? ptrdiff_t is the signed version of size_t. The complaint is not that you are converting from unsigned to signed, but that you are converting from 64-bit to 32-bit. -Steve
Jun 20 2020
On 6/20/20 11:22 PM, Danni Coy wrote:On Sun, Jun 21, 2020 at 9:40 AM Avrina via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Saturday, 20 June 2020 at 18:15:27 UTC, Steven Schveighoffer wrote:On 6/20/20 12:00 PM, Danni Coy wrote:I tried explicitly making x and y ints and I got a depreciation warning.foreach(ptrdiff_t y, ref row; offsetMap) is that what you wanted? ptrdiff_t is the signed version of size_t. The complaint is not that you are converting from unsigned to signed, but that you are converting from 64-bit to 32-bit.So this entire conversation is incorrect -- there is no promotion to unsigned happening. What is the bug with size_t implicitly casting to float? I would think it would work. -SteveWhy isn't that deprecated as well? implicitly converting from ulong to long is an error as much as ulong to uint.It turns out this line is the bigger problem. immutable SDL_FPair offset = { center.x - x, y - center.y }; FPair is a struct SDL_FPair { float x; float y; ... if those values were ints. dmd will not allow a downcast from ulong to int (the compiler would have caught the issue for me) but it will allow casting ulong to float which is why It took me a couple of hours with a debugger trying to find the bug.
Jun 22 2020
On Monday, 22 June 2020 at 12:42:26 UTC, Steven Schveighoffer wrote:On 6/20/20 11:22 PM, Danni Coy wrote:I think the issue is that it's converting the ulongs to float, which are actually negative and not positive: center.x - x and y - center.y might become negative and because it's a ulong it will be a huge number, then converting to float it will be a huge float number instead of some normal negative number. so: size_t centerX = 1; size_t x = 3; float f = centerX - x; // <- this is not -2, this is 1.84467e+19 without any warnings or deprecations printed Meanwhile an implicit cast to int is disallowed (error) but it would actually contain the correct result and nobody would have ever found it.On Sun, Jun 21, 2020 at 9:40 AM Avrina via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Saturday, 20 June 2020 at 18:15:27 UTC, Steven Schveighoffer wrote:On 6/20/20 12:00 PM, Danni Coy wrote:I tried explicitly making x and y ints and I got a depreciation warning.foreach(ptrdiff_t y, ref row; offsetMap) is that what you wanted? ptrdiff_t is the signed version of size_t. The complaint is not that you are converting from unsigned to signed, but that you are converting from 64-bit to 32-bit.So this entire conversation is incorrect -- there is no promotion to unsigned happening. What is the bug with size_t implicitly casting to float? I would think it would work. -SteveWhy isn't that deprecated as well? implicitly converting from ulong to long is an error as much as ulong to uint.It turns out this line is the bigger problem. immutable SDL_FPair offset = { center.x - x, y - center.y }; FPair is a struct SDL_FPair { float x; float y; ... if those values were ints. dmd will not allow a downcast from ulong to int (the compiler would have caught the issue for me) but it will allow casting ulong to float which is why It took me a couple of hours with a debugger trying to find the bug.
Jun 22 2020
On 6/22/20 9:02 AM, WebFreak001 wrote:On Monday, 22 June 2020 at 12:42:26 UTC, Steven Schveighoffer wrote:But the OP rejected the idea of using ptrdiff_t (or did he?), which would solve that problem. It's really hard to tell what the problem is without more definition or explanation. -SteveOn 6/20/20 11:22 PM, Danni Coy wrote:I think the issue is that it's converting the ulongs to float, which are actually negative and not positive: center.x - x and y - center.y might become negative and because it's a ulong it will be a huge number, then converting to float it will be a huge float number instead of some normal negative number. so: size_t centerX = 1; size_t x = 3; float f = centerX - x; // <- this is not -2, this is 1.84467e+19 without any warnings or deprecations printed Meanwhile an implicit cast to int is disallowed (error) but it would actually contain the correct result and nobody would have ever found it.On Sun, Jun 21, 2020 at 9:40 AM Avrina via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Saturday, 20 June 2020 at 18:15:27 UTC, Steven Schveighoffer wrote:On 6/20/20 12:00 PM, Danni Coy wrote:I tried explicitly making x and y ints and I got a depreciation warning.foreach(ptrdiff_t y, ref row; offsetMap) is that what you wanted? ptrdiff_t is the signed version of size_t. The complaint is not that you are converting from unsigned to signed, but that you are converting from 64-bit to 32-bit.So this entire conversation is incorrect -- there is no promotion to unsigned happening. What is the bug with size_t implicitly casting to float? I would think it would work.Why isn't that deprecated as well? implicitly converting from ulong to long is an error as much as ulong to uint.It turns out this line is the bigger problem. immutable SDL_FPair offset = { center.x - x, y - center.y }; FPair is a struct SDL_FPair { float x; float y; ... if those values were ints. dmd will not allow a downcast from ulong to int (the compiler would have caught the issue for me) but it will allow casting ulong to float which is why It took me a couple of hours with a debugger trying to find the bug.
Jun 22 2020
On Monday, 22 June 2020 at 13:24:32 UTC, Steven Schveighoffer wrote:But the OP rejected the idea of using ptrdiff_t (or did he?), which would solve that problem. It's really hard to tell what the problem is without more definition or explanation.OP is precise: On Saturday, 20 June 2020 at 16:00:40 UTC, Danni Coy wrote:more specifically I didn't want them to be unsignedThe discussion was just derailed.
Jun 22 2020
On 6/22/20 2:19 PM, Kagamin wrote:On Monday, 22 June 2020 at 13:24:32 UTC, Steven Schveighoffer wrote:That is exactly what declaring the variables to be ptrdiff_t would do. I guess he didn't specifically reject that answer, but proceeded to say something else is the "bigger problem". If using ptrdiff_t doesn't work, then I would have to have more information about why it doesn't work. -SteveBut the OP rejected the idea of using ptrdiff_t (or did he?), which would solve that problem. It's really hard to tell what the problem is without more definition or explanation.OP is precise: On Saturday, 20 June 2020 at 16:00:40 UTC, Danni Coy wrote:more specifically I didn't want them to be unsignedThe discussion was just derailed.
Jun 22 2020
On Monday, 22 June 2020 at 18:37:41 UTC, Steven Schveighoffer wrote:I guess he didn't specifically reject that answer, but proceeded to say something else is the "bigger problem".The problem is that nonnumbers are converted to float, but they were intended to be compatible only with signed integers, such conversion doesn't change the bit pattern and most of the time the last bit is useless anyway.
Jun 27 2020
And processor doesn't even support conversion between unsigned integers and floating point numbers.
Jun 27 2020
On Saturday, 20 June 2020 at 23:36:25 UTC, Avrina wrote:On Saturday, 20 June 2020 at 18:15:27 UTC, Steven Schveighoffer wrote:No. conversion of ulong to uint loses 32 times more data than conversion to long does.On 6/20/20 12:00 PM, Danni Coy wrote:Why isn't that deprecated as well? implicitly converting from ulong to long is an error as much as ulong to uint.I tried explicitly making x and y ints and I got a depreciation warning.foreach(ptrdiff_t y, ref row; offsetMap) is that what you wanted? ptrdiff_t is the signed version of size_t. The complaint is not that you are converting from unsigned to signed, but that you are converting from 64-bit to 32-bit. -Steve
Jun 21 2020
On Sunday, 21 June 2020 at 10:12:22 UTC, Patrick Schluter wrote:On Saturday, 20 June 2020 at 23:36:25 UTC, Avrina wrote:Lol, it's not linear friend. You lose around 18446744069414584319 values from ulong to uint, you lose 9223372032559808512 from ulong to long. Which is about 2 times less data. Which makes sense as it is basically 2^64 - 2^63, so of course it would only be x2 -- not x32.On Saturday, 20 June 2020 at 18:15:27 UTC, Steven Schveighoffer wrote:No. conversion of ulong to uint loses 32 times more data than conversion to long does.On 6/20/20 12:00 PM, Danni Coy wrote:Why isn't that deprecated as well? implicitly converting from ulong to long is an error as much as ulong to uint.I tried explicitly making x and y ints and I got a depreciation warning.foreach(ptrdiff_t y, ref row; offsetMap) is that what you wanted? ptrdiff_t is the signed version of size_t. The complaint is not that you are converting from unsigned to signed, but that you are converting from 64-bit to 32-bit. -Steve
Jun 21 2020
On Sunday, 21 June 2020 at 13:17:54 UTC, Avrina wrote:On Sunday, 21 June 2020 at 10:12:22 UTC, Patrick Schluter wrote:Not that it should matter how much, it's a problem either way.On Saturday, 20 June 2020 at 23:36:25 UTC, Avrina wrote:Lol, it's not linear friend. You lose around 18446744069414584319 values from ulong to uint, you lose 9223372032559808512 from ulong to long. Which is about 2 times less data. Which makes sense as it is basically 2^64 - 2^63, so of course it would only be x2 -- not x32.On Saturday, 20 June 2020 at 18:15:27 UTC, Steven Schveighoffer wrote:No. conversion of ulong to uint loses 32 times more data than conversion to long does.On 6/20/20 12:00 PM, Danni Coy wrote:Why isn't that deprecated as well? implicitly converting from ulong to long is an error as much as ulong to uint.I tried explicitly making x and y ints and I got a depreciation warning.foreach(ptrdiff_t y, ref row; offsetMap) is that what you wanted? ptrdiff_t is the signed version of size_t. The complaint is not that you are converting from unsigned to signed, but that you are converting from 64-bit to 32-bit. -Steve
Jun 21 2020
On Sunday, 21 June 2020 at 13:17:54 UTC, Avrina wrote:On Sunday, 21 June 2020 at 10:12:22 UTC, Patrick Schluter wrote:losing 1 bit vs losing 32 bits. The exponentiation is irrelevant.On Saturday, 20 June 2020 at 23:36:25 UTC, Avrina wrote:Lol, it's not linear friend.On Saturday, 20 June 2020 at 18:15:27 UTC, Steven Schveighoffer wrote:No. conversion of ulong to uint loses 32 times more data than conversion to long does.On 6/20/20 12:00 PM, Danni Coy wrote:Why isn't that deprecated as well? implicitly converting from ulong to long is an error as much as ulong to uint.I tried explicitly making x and y ints and I got a depreciation warning.foreach(ptrdiff_t y, ref row; offsetMap) is that what you wanted? ptrdiff_t is the signed version of size_t. The complaint is not that you are converting from unsigned to signed, but that you are converting from 64-bit to 32-bit. -SteveYou lose around 18446744069414584319 values from ulong to uint, you lose 9223372032559808512 from ulong to long. Which is about 2 times less data. Which makes sense as it is basically 2^64 - 2^63, so of course it would only be x2 -- not x32.Not that it should matter how much, it's a problem either way.But a much less severe one. Overflowing a 32 bit index on a 64 bit machine with the data sizes that exist today (files of more than 4GiB are not rare, zips, videos and databases). 9 223 372 032 559 808 512 is still 32768x bigger than 281 474 976 710 656, the biggest addressable range on x86_64.
Jun 21 2020
On Sunday, 21 June 2020 at 19:33:47 UTC, Patrick Schluter wrote:On Sunday, 21 June 2020 at 13:17:54 UTC, Avrina wrote:It is when that 1 bit is worth 9223372032559808512On Sunday, 21 June 2020 at 10:12:22 UTC, Patrick Schluter wrote:losing 1 bit vs losing 32 bits. The exponentiation is irrelevant.On Saturday, 20 June 2020 at 23:36:25 UTC, Avrina wrote:Lol, it's not linear friend.On Saturday, 20 June 2020 at 18:15:27 UTC, Steven Schveighoffer wrote:No. conversion of ulong to uint loses 32 times more data than conversion to long does.On 6/20/20 12:00 PM, Danni Coy wrote:Why isn't that deprecated as well? implicitly converting from ulong to long is an error as much as ulong to uint.I tried explicitly making x and y ints and I got a depreciation warning.foreach(ptrdiff_t y, ref row; offsetMap) is that what you wanted? ptrdiff_t is the signed version of size_t. The complaint is not that you are converting from unsigned to signed, but that you are converting from 64-bit to 32-bit. -SteveThat's an index to an array, not a file. The File api uses ulong (as it should) and doesn't use size_t. If you are using memory mapped files, that isn't portable and you are going to have issues with performance. Otherwise a 32-bit index is sufficient, you aren't ever going to have an array that big that uses up that much memory in the system. So again, doesn't matter. There's a reason no one has complained about this "bug" for 20 years, and the only reason it was "discovered" was because it was inconsistent with foreach_reverse.You lose around 18446744069414584319 values from ulong to uint, you lose 9223372032559808512 from ulong to long. Which is about 2 times less data. Which makes sense as it is basically 2^64 - 2^63, so of course it would only be x2 -- not x32.Not that it should matter how much, it's a problem either way.But a much less severe one. Overflowing a 32 bit index on a 64 bit machine with the data sizes that exist today (files of more than 4GiB are not rare, zips, videos and databases). 9 223 372 032 559 808 512 is still 32768x bigger than 281 474 976 710 656, the biggest addressable range on x86_64.
Jun 21 2020
On 6/20/20 7:36 PM, Avrina wrote:On Saturday, 20 June 2020 at 18:15:27 UTC, Steven Schveighoffer wrote:It's not an error as you don't lose information. In this case, you are losing nothing, as there are no systems with exabytes of RAM (i.e. an array size will never be big enough to overflow a long). -SteveOn 6/20/20 12:00 PM, Danni Coy wrote:Why isn't that deprecated as well? implicitly converting from ulong to long is an error as much as ulong to uint.I tried explicitly making x and y ints and I got a depreciation warning.foreach(ptrdiff_t y, ref row; offsetMap) is that what you wanted? ptrdiff_t is the signed version of size_t. The complaint is not that you are converting from unsigned to signed, but that you are converting from 64-bit to 32-bit.
Jun 22 2020