www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Re: ref, safety,

reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
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.
Sep 23 2012
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
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
Sep 23 2012
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
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
Sep 23 2012
prev sibling next sibling parent "Peter Alexander" <peter.alexander.au gmail.com> writes:
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.
Sep 23 2012
prev sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
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.
Sep 23 2012