Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
September 19, 2011 A little puzzle | ||||
---|---|---|---|---|
| ||||
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 |
September 19, 2011 Re: A little puzzle | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | 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 |
September 19, 2011 Re: A little puzzle | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | 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);
}
|
September 19, 2011 Re: A little puzzle | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjaeraas | 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)?
|
September 19, 2011 Re: A little puzzle | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam Burton | 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.
|
September 20, 2011 Re: A little puzzle | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjaeraas | 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/ |
Copyright © 1999-2021 by the D Language Foundation