| Thread overview | |||||||||
|---|---|---|---|---|---|---|---|---|---|
|
September 23, 2012 Re: ref, safety, and warnings (was: ref and out required for function calls) | ||||
|---|---|---|---|---|
| ||||
On 9/7/12, Kevin McTaggart <kevin.mctaggart@drdc-rddc.gc.ca> wrote: > snip There's one thing nobody mentioned yet, and that is that we're already using this syntax in the language -- in foreach loops: struct Foo { int x; } Foo[] arr = [{4}, {5}, {6}]; foreach (idx, ref val; arr) { val.x = idx; } However I'd like to see a custom compiler warning switch that would warn me if I tried to call opAssign on a fundamental or struct type in a foreach loop with a non-ref foreach parameter: foreach (idx, val; arr) { val.x = idx; // clearly a bug, but lacks warning } I've had *numerous* occasions over the last few years where I've had this bug happen to me. Structs and classes have different semantics and when you're working in a large codebase that uses a combination of classes and structs it's too easy to forget to add 'ref' to a foreach parameter because you're looping over struct instances of some range rather than class references. I'd rather this be a special warning since enabling it by default might be annoying if you really want to opAssign to temporaries. I think the current mechanism we have (shove all warnings into the "-w" switch and offer no customization) is lacking. I'd propose we kept the current '-w' switch but also added options only enable or disable specific warnings, e.g.: dmd -we001 -we002 -> only enable warnings 001 and 002 dmd -w -wd001 -wd002 -> enable all warnings, except 001 and 002 which are disabled Then we could keep a list of warnings on dlang.org and provide helpful info on when these warnings occur and what the user can do to fix his code. For example look at how empty the warnings page is now: http://dlang.org/warnings.html I'd be willing to help out write the new warnings page. | ||||
September 23, 2012 Re: ref, safety, and warnings | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | Andrej Mitrovic: > However I'd like to see a custom compiler warning switch that would > warn me if I tried to call opAssign on a fundamental or struct type in > a foreach loop with a non-ref foreach parameter: > > foreach (idx, val; arr) > { > val.x = idx; // clearly a bug, but lacks warning > } > > I've had *numerous* occasions over the last few years where I've had this bug happen to me. The same for me. Most people seem to not care for this problem, I don't understand why. But I think it's a common source for bugs in D programs. D design must take in account not just error-prone features inherited from C, but also to avoid bug-prone situations created by D-specific features. C# designers have avoided this problem: http://msdn.microsoft.com/en-us/library/04t3s14w.aspx A possible solution is to require an explicit annotation if you want to modify just the copy: foreach (idx, @copy val; arr) val.x = idx; But maybe better is to do as in C# and turn "val" (and idx!) into a const on default, and require an annotation if you want to modify the copy: foreach (idx, @mutable val; arr) val.x = idx; Bye, bearophile | |||
September 23, 2012 Re: ref, safety, and warnings | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | Andrej Mitrovic: > However I'd like to see a custom compiler warning switch that would > warn me if I tried to call opAssign on a fundamental or struct type in > a foreach loop with a non-ref foreach parameter: > > foreach (idx, val; arr) > { > val.x = idx; // clearly a bug, but lacks warning > } > > I've had *numerous* occasions over the last few years where I've had this bug happen to me. The same for me. Most people seem to not care for this problem, I don't understand why. But I think it's a common source for bugs in D programs. D design must take in account not just error-prone features inherited from C, but also to avoid bug-prone situations created by D-specific features. C# designers have avoided this problem: http://msdn.microsoft.com/en-us/library/04t3s14w.aspx A possible solution is to require an explicit annotation if you want to modify just the copy: foreach (idx, @copy val; arr) val.x = idx; But maybe better is to do as in C# and turn "val" (and idx!) into a const on default, and require an annotation if you want to modify the copy: foreach (idx, @mutable val; arr) val.x = idx; Bye, bearophile | |||
September 23, 2012 Re: ref, safety, and warnings | ||||
|---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Sunday, 23 September 2012 at 18:43:08 UTC, bearophile wrote:
>> foreach (idx, val; arr)
>> {
>> val.x = idx; // clearly a bug, but lacks warning
>> }
>>
>> I've had *numerous* occasions over the last few years where I've had this bug happen to me.
>
> The same for me. Most people seem to not care for this problem, I
> don't understand why. But I think it's a common source for bugs
> in D programs. D design must take in account not just error-prone
> features inherited from C, but also to avoid bug-prone situations
> created by D-specific features.
Me too. I think this is the most common bug in my programs caused by the language.
| |||
September 23, 2012 Re: ref, safety, and warnings (was: ref and out required for function calls) | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | On 09/23/2012 07:37 PM, Andrej Mitrovic wrote:
> On 9/7/12, Kevin McTaggart <kevin.mctaggart@drdc-rddc.gc.ca> wrote:
>> snip
>
> There's one thing nobody mentioned yet, and that is that we're already
> using this syntax in the language -- in foreach loops:
>
> struct Foo { int x; }
> Foo[] arr = [{4}, {5}, {6}];
>
> foreach (idx, ref val; arr)
> {
> val.x = idx;
> }
> ...
That is not true. The only 'ref' in that code is a declaration site annotation.
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply