Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
December 20, 2018 Weird const behavior | ||||
---|---|---|---|---|
| ||||
I have the following piece of code: `````````````````````` #!/bin/env dub /+ dub.sdl: name: day2 +/ import std.algorithm.iteration : group; import std.stdio; void main() { const auto a = group("simon"); auto b = group("simon"); writeln(a == b); writeln(); writeln(a); writeln(); writeln(b); } `````````````````````` When I run it, it gives me this output: `````````````````````` true const(Group!("a == b", string))("imon", Tuple!(dchar, uint)('s', 1)) [Tuple!(dchar, uint)('s', 1), Tuple!(dchar, uint)('i', 1), Tuple!(dchar, uint)('m', 1), Tuple!(dchar, uint)('o', 1), Tuple!(dchar, uint)('n', 1)] `````````````````````` The only difference (code-wise) is the `const` keyword. I've tried with both `ldc` and `dmd` with same result. Why is the output different when the variable is `const`? |
December 20, 2018 Re: Weird const behavior | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simón Oroño | On Thursday, 20 December 2018 at 01:37:59 UTC, Simón Oroño wrote:
> The only difference (code-wise) is the `const` keyword. I've tried with both `ldc` and `dmd` with same result. Why is the output different when the variable is `const`?
A const range cannot be iterated by a generic template (without additional work, at least), so writeln just sees it as a blob instead of something it can loop over.
|
December 20, 2018 Re: Weird const behavior | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | On Thursday, 20 December 2018 at 02:05:53 UTC, Adam D. Ruppe wrote:
> On Thursday, 20 December 2018 at 01:37:59 UTC, Simón Oroño wrote:
>> The only difference (code-wise) is the `const` keyword. I've tried with both `ldc` and `dmd` with same result. Why is the output different when the variable is `const`?
>
> A const range cannot be iterated by a generic template (without additional work, at least), so writeln just sees it as a blob instead of something it can loop over.
I'm not the OP but I'd like to understand this:
When he is comparing "a == b" it returns true, but then it diverges on the usability.
So a == b compares just values without types?
But is this right? I mean if they are equal shouldn't they have the same behavior?
Marko.
|
December 20, 2018 Re: Weird const behavior | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marko | On Thursday, 20 December 2018 at 14:49:10 UTC, Marko wrote:
> But is this right? I mean if they are equal shouldn't they have the same behavior?
I don't think so:
float a = 1.0;
long b = 1;
writeln(a == b);
writeln(a/2 == b/2);
|
December 20, 2018 Re: Weird const behavior | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marko | On 12/20/18 9:49 AM, Marko wrote:
> On Thursday, 20 December 2018 at 02:05:53 UTC, Adam D. Ruppe wrote:
>> On Thursday, 20 December 2018 at 01:37:59 UTC, Simón Oroño wrote:
>>> The only difference (code-wise) is the `const` keyword. I've tried with both `ldc` and `dmd` with same result. Why is the output different when the variable is `const`?
>>
>> A const range cannot be iterated by a generic template (without additional work, at least), so writeln just sees it as a blob instead of something it can loop over.
>
> I'm not the OP but I'd like to understand this:
>
> When he is comparing "a == b" it returns true, but then it diverges on the usability.
>
> So a == b compares just values without types?
>
> But is this right? I mean if they are equal shouldn't they have the same behavior?
>
> Marko.
It's really how opEquals is marked.
opEquals for structs (without a specific implementation), is marked as a combination of comparing all the fields, whatever they are marked. Any basic types are comparable whether they are const or not. So most likely the range struct's opEquals is marked const.
However, popFront is likely not const. In some rare cases it can be (i.e. an infinite range of a single value). If the range cannot be operated, isInputRange returns false.
-Steve
|
December 20, 2018 Re: Weird const behavior | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrea Fontana | On Thursday, 20 December 2018 at 15:15:42 UTC, Andrea Fontana wrote:
> On Thursday, 20 December 2018 at 14:49:10 UTC, Marko wrote:
>> But is this right? I mean if they are equal shouldn't they have the same behavior?
>
> I don't think so:
>
> float a = 1.0;
> long b = 1;
>
> writeln(a == b);
> writeln(a/2 == b/2);
Of course you can play around:
uint positive_one = 1;
short minus_one = -1;
uint max_int = 4294967295;
writeln(minus_one > positive_one); // true
writeln(minus_one == max_int); // true
Because promotion and implicit casting. But like I said this is sometimes confusion, and on the OP example it's worth.
Marko.
|
December 20, 2018 Re: Weird const behavior | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Thursday, 20 December 2018 at 15:17:31 UTC, Steven Schveighoffer wrote:
> It's really how opEquals is marked.
>
> opEquals for structs (without a specific implementation), is marked as a combination of comparing all the fields, whatever they are marked. Any basic types are comparable whether they are const or not. So most likely the range struct's opEquals is marked const.
>
> However, popFront is likely not const. In some rare cases it can be (i.e. an infinite range of a single value). If the range cannot be operated, isInputRange returns false.
>
> -Steve
I know about promotion / implicit casting, but I always find this is a but awkward when comparing objects or structs it's equal but acts differently.
But I'm may be the minority. :)
Marko.
|
Copyright © 1999-2021 by the D Language Foundation