www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - with and shadowing variables

reply Anonymouse <asdf asdf.net> writes:
Can this be made a compiler warning?

struct Foo
{
     int i;
}

void main()
{
     Foo foo;

     with (foo)
     {
         i = 42;
         int i;
         i = 24;
     }
}

I'm hesitant to file a bug because it'll just be immediately 
closed with a link to 
https://dlang.org/spec/statement.html#WithStatement. I understand 
that's how it works, but it's weird and weak to human mistakes.
Jul 22 2018
next sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Sunday, July 22, 2018 12:13:43 Anonymouse via Digitalmars-d wrote:
 Can this be made a compiler warning?

 struct Foo
 {
      int i;
 }

 void main()
 {
      Foo foo;

      with (foo)
      {
          i = 42;
          int i;
          i = 24;
      }
 }

 I'm hesitant to file a bug because it'll just be immediately
 closed with a link to
 https://dlang.org/spec/statement.html#WithStatement. I understand
 that's how it works, but it's weird and weak to human mistakes.
that it would be in the spirit of the restrictions that with already has, and I think that there's a pretty clear argument to be made that allowing it is too error-prone, but maybe someone will have a reason why it doesn't make sense to disallow it. I don't know. Regardless, I would suggest that you open an enhancement request. I would guess that it's straightforward enough that a DIP isn't reauired so long as Walter approves of it, but I don't know. Either way, if it's in bugzilla, then it stands a much better chance of happening than if the only record of it is here. - Jonathan M Davis
Jul 22 2018
parent Jim Balter <Jim Balter.name> writes:
On Sunday, 22 July 2018 at 14:05:45 UTC, Jonathan M Davis wrote:
 On Sunday, July 22, 2018 12:13:43 Anonymouse via Digitalmars-d 
 wrote:
 Can this be made a compiler warning?

 struct Foo
 {
      int i;
 }

 void main()
 {
      Foo foo;

      with (foo)
      {
          i = 42;
          int i;
          i = 24;
      }
 }

 I'm hesitant to file a bug because it'll just be immediately 
 closed with a link to 
 https://dlang.org/spec/statement.html#WithStatement. I 
 understand that's how it works, but it's weird and weak to 
 human mistakes.
certainly be argued that it would be in the spirit of the restrictions that with already has, and I think that there's a pretty clear argument to be made that allowing it is too error-prone, but maybe someone will have a reason why it doesn't make sense to disallow it. I don't know. Regardless, I would suggest that you open an enhancement request. I would guess that it's straightforward enough that a DIP isn't reauired so long as Walter approves of it, but I don't know. Either way, if it's in bugzilla, then it stands a much better chance of happening than if the only record of it is here. - Jonathan M Davis
the with block must not also be a member of Foo, to prevent a silent change in the meaning of the code if that symbol gets happens. Nothing like that applies here ... clearly the two `i's are different, since you can't use a symbol before it's defined (except at top level). You might want to argue that it should be disallowed (I wouldn't), but I don't think you can use "the
Jul 23 2018
prev sibling next sibling parent reply Jim Balter <Jim Balter.name> writes:
On Sunday, 22 July 2018 at 12:13:43 UTC, Anonymouse wrote:
 Can this be made a compiler warning?

 struct Foo
 {
     int i;
 }

 void main()
 {
     Foo foo;

     with (foo)
     {
         i = 42;
         int i;
         i = 24;
     }
 }

 I'm hesitant to file a bug because it'll just be immediately 
 closed with a link to 
 https://dlang.org/spec/statement.html#WithStatement. I 
 understand that's how it works, but it's weird and weak to 
 human mistakes.
Do you have an actual case where it was a problem, as opposed to a contrived example with semantically empty identifiers? I recently saw another comment objecting to `with` altogether as being obfuscating because you can't tell which symbols are qualified by the symbol in the with clause, when the obfuscation was clearly due to the meaningless names in the poster's example.
Jul 23 2018
parent Anonymouse <asdf asdf.net> writes:
On Monday, 23 July 2018 at 12:01:19 UTC, Jim Balter wrote:
 Do you have an actual case where it was a problem, as opposed 
 to a contrived example with semantically empty identifiers? I 
 recently saw another comment objecting to `with` altogether as 
 being obfuscating because you can't tell which symbols are 
 qualified by the symbol in the with clause, when the 
 obfuscation was  clearly due to the meaningless names in the 
 poster's example.
Copy/pasted but changed some bits for clarity. struct IRCServer { // ... string prefixchars; string prefixes; // <-- } struct IRCBot { // ... IRCServer server; } struct IRCParser { // ... IRCBot bot; } IRCParser parser; // string content == "EXCEPTS INVEX PREFIX=(Yqaohv)!~& %+"; foreach (entry; content.splitter(" ")) { // Roughly rewritten splitting auto split = entry.findSplit("="); string key = split[0]; string value = split[2]; with (parser.bot.server) switch (key) { case "PREFIX": // PREFIX=(Yqaohv)!~& %+ import std.format : formattedRead; string modes; string prefixes; // <-- value.formattedRead("(%s)%s", modes, prefixes); foreach (immutable i; 0..modes.length) { prefixchars[prefixes[i]] = modes[i]; // parser.bot.server.prefixchars prefixes ~= modes[i]; // <-- accidental local prefixes instead of parser.bot.server.prefixes } break; // ... default: break; } https://github.com/zorael/kameloso/blob/93002da193eac2dfbfeb6c8756feb2d74a345530/source/kameloso/irc.d#L1887
Jul 23 2018
prev sibling next sibling parent baz <b2.temp gmx.com> writes:
On Sunday, 22 July 2018 at 12:13:43 UTC, Anonymouse wrote:
 I'm hesitant to file a bug because it'll just be immediately 
 closed with a link to 
 https://dlang.org/spec/statement.html#WithStatement. I 
 understand that's how it works, but it's weird and weak to 
 human mistakes.
IMO the only reasonable thing to do with `with` is not to use it, generally speaking. Maybe in D the only exception would be with an named enum ( the final switch pattern). But otherwise the WithStatement, D or not, is known for being a big nono.
Jul 23 2018
prev sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 7/22/18 8:13 AM, Anonymouse wrote:
 Can this be made a compiler warning?
 
 struct Foo
 {
      int i;
 }
 
 void main()
 {
      Foo foo;
 
      with (foo)
      {
          i = 42;
          int i;
          i = 24;
      }
 }
 
 I'm hesitant to file a bug because it'll just be immediately closed with 
 a link to https://dlang.org/spec/statement.html#WithStatement. I 
 understand that's how it works, but it's weird and weak to human mistakes.
I'm with Jonathan, it should be an error. It shouldn't matter what scope you declared `i` in, just when you use it, the ambiguity should trigger. The fix is super-simple, name it something else! Note that this won't fix other ambiguities. For example, if Foo has an opDispatch that matches "i", or `i` is a UFCS function (actually, I don't know if UFCS works using `with`). -Steve
Jul 23 2018
parent Anonymouse <asdf asdf.net> writes:
On Monday, 23 July 2018 at 17:26:16 UTC, Steven Schveighoffer 
wrote:
 On 7/22/18 8:13 AM, Anonymouse wrote:
 Can this be made a compiler warning?
 
 struct Foo
 {
      int i;
 }
 
 void main()
 {
      Foo foo;
 
      with (foo)
      {
          i = 42;
          int i;
          i = 24;
      }
 }
 
 I'm hesitant to file a bug because it'll just be immediately 
 closed with a link to 
 https://dlang.org/spec/statement.html#WithStatement. I 
 understand that's how it works, but it's weird and weak to 
 human mistakes.
I'm with Jonathan, it should be an error. It shouldn't matter what scope you declared `i` in, just when you use it, the ambiguity should trigger. The fix is super-simple, name it something else!
Filed as https://issues.dlang.org/show_bug.cgi?id=19113.
Jul 24 2018