www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - A little puzzle

reply bearophile <bearophileHUGS lycos.com> writes:
A tiny puzzle I've shown on IRC. This is supposed to create an inverted array
of cards, but what does it print instead?

import std.stdio, std.algorithm, std.range;
void main() {
    int[52] cards;
    copy(iota(cards.length - 1, -1, -1), cards[]);
    writeln(cards);
}

Bye,
bearophile
Sep 19 2011
next sibling parent reply "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On Mon, 19 Sep 2011 23:20:47 +0200, bearophile <bearophileHUGS lycos.com>  
wrote:

 A tiny puzzle I've shown on IRC. This is supposed to create an inverted  
 array of cards, but what does it print instead?

 import std.stdio, std.algorithm, std.range;
 void main() {
     int[52] cards;
     copy(iota(cards.length - 1, -1, -1), cards[]);
     writeln(cards);
 }
Gawds, that's an ugly bug. For those who can't spot it, typeof(cards.length) == uint, hence -1 is converted to a uint (4_294_967_295, to be exact). iota then says 'that's fine, I'll just return an empty range for you.' Solution: knock some sense into integral promotion rules. Workaround: cast(int)cards.length. What was the rationale for having unsigned array lengths, again? -- Simen
Sep 19 2011
next sibling parent reply Adam Burton <adz21c gmail.com> writes:
Simen Kjaeraas wrote:

 On Mon, 19 Sep 2011 23:20:47 +0200, bearophile <bearophileHUGS lycos.com>
 wrote:
 
 A tiny puzzle I've shown on IRC. This is supposed to create an inverted
 array of cards, but what does it print instead?

 import std.stdio, std.algorithm, std.range;
 void main() {
     int[52] cards;
     copy(iota(cards.length - 1, -1, -1), cards[]);
     writeln(cards);
 }
Gawds, that's an ugly bug. For those who can't spot it, typeof(cards.length) == uint, hence -1 is converted to a uint (4_294_967_295, to be exact). iota then says 'that's fine, I'll just return an empty range for you.' Solution: knock some sense into integral promotion rules. Workaround: cast(int)cards.length. What was the rationale for having unsigned array lengths, again?
That's not what happened for me. It failed to compile for me due to ElementType of Range1 not matching Range2 ElementType. Could this be due to using 64bit (size_t is ulong)?
Sep 19 2011
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 09/20/2011 12:50 AM, Adam Burton wrote:
 Simen Kjaeraas wrote:

 On Mon, 19 Sep 2011 23:20:47 +0200, bearophile<bearophileHUGS lycos.com>
 wrote:

 A tiny puzzle I've shown on IRC. This is supposed to create an inverted
 array of cards, but what does it print instead?

 import std.stdio, std.algorithm, std.range;
 void main() {
      int[52] cards;
      copy(iota(cards.length - 1, -1, -1), cards[]);
      writeln(cards);
 }
Gawds, that's an ugly bug. For those who can't spot it, typeof(cards.length) == uint, hence -1 is converted to a uint (4_294_967_295, to be exact). iota then says 'that's fine, I'll just return an empty range for you.' Solution: knock some sense into integral promotion rules. Workaround: cast(int)cards.length. What was the rationale for having unsigned array lengths, again?
That's not what happened for me. It failed to compile for me due to ElementType of Range1 not matching Range2 ElementType. Could this be due to using 64bit (size_t is ulong)?
If you recompile with the -m32 switch it should be accepted.
Sep 19 2011
prev sibling parent "Regan Heath" <regan netmail.co.nz> writes:
On Mon, 19 Sep 2011 23:09:45 +0100, Simen Kjaeraas  
<simen.kjaras gmail.com> wrote:

 On Mon, 19 Sep 2011 23:20:47 +0200, bearophile  
 <bearophileHUGS lycos.com> wrote:

 A tiny puzzle I've shown on IRC. This is supposed to create an inverted  
 array of cards, but what does it print instead?

 import std.stdio, std.algorithm, std.range;
 void main() {
     int[52] cards;
     copy(iota(cards.length - 1, -1, -1), cards[]);
     writeln(cards);
 }
Gawds, that's an ugly bug. For those who can't spot it, typeof(cards.length) == uint, hence -1 is converted to a uint (4_294_967_295, to be exact). iota then says 'that's fine, I'll just return an empty range for you.' Solution: knock some sense into integral promotion rules. Workaround: cast(int)cards.length. What was the rationale for having unsigned array lengths, again?
Well.. logically it makes sense as arrays cannot have negative lengths, but practically, this bug is what happens as a result. This is the reason I typically use signed int for lengths, unless I expect the length to exceed max signed int. It's also a good idea if you ever do any subtraction/calculation with them, as you don't want to underflow to max signed int ever. It means that in my daily work I have to cast the return value of strlen() everywhere (cos my compiler complains, but only in 64 bit mode..).. I mean, really, when are you going to have a string which is longer than max signed int?! It's just nonsensical. -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Sep 20 2011
prev sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 09/19/2011 11:20 PM, bearophile wrote:
 A tiny puzzle I've shown on IRC. This is supposed to create an inverted array
of cards, but what does it print instead?

 import std.stdio, std.algorithm, std.range;
 void main() {
      int[52] cards;
      copy(iota(cards.length - 1, -1, -1), cards[]);
      writeln(cards);
 }

 Bye,
 bearophile
The same as this code, of course! import std.stdio, std.algorithm, std.range; void main() { int[52] cards; for(auto i=cards.length-1,v=0; i>-1; i--, v++) cards[i]=v; writeln(cards); }
Sep 19 2011