Shadowing of members

H. S. Teoh hsteoh at quickfur.ath.cx
Wed Jan 9 13:28:46 PST 2013


On Wed, Jan 09, 2013 at 10:17:00PM +0100, comco wrote:
> On Wednesday, 9 January 2013 at 20:36:16 UTC, Benjamin Thaut wrote:
> >After some refactoring I had a series of bugs that came from
> >renaming class members so that the following situation was
> >present.
> >
> >
> >class foo
> >{
> >  float a;
> >
> >  void doSomething()
> >  {
> >    float a;
> >    a = a * 2.0;
> >  }
> >}
> >
> >The local variable a shadows the member a after the refactoring
> >and therefore this code will no longer work as expected. This was
> >quite time consuming to track down. So I wanted to ask if we want
> >to prevent that with a warning or even an error? D does not allow
> >shadowing of local variables, so why is it allowed for members?
> >
> >Kind Regards
> >Benjamin Thaut
> 
> I don't think an error will be appropriate, because this a can be a
> protected member of the super-super-super class and it won't be nice
> to be forced to use a different name. But another view on this is
> that it behaves consistently with the case in which a function
> parameter shadows a member.
> I won't like this code:
> class Pu {
>    int a, b;
>    this(int a, int b) {
>        this.a = a;
>        this.b = b;
>    }
> }
> 
> to issue warnings for a and b.

I used to write code like that too, but then I ran into some nasty
ambiguity bugs, and now I'm in favor of prohibiting local variables
shadowing class members. It's just *too* easy to make a mistake, and
have the code write something to a local variable (which is lost upon
scope exit) instead of a class member, or vice versa.

Add class template parameters to the mix, and it quickly becomes a
minefield. I think this kind of shadowing should not be allowed.

Even if there's a protected member of a super-super-super class, I'd
rather know about a name conflict than to write code like this:

	class B {
		protected int a=123;
	}

	class A : B {
		int f(int b) {
			//int a;	// <--- I forgot to write this line
			...
			a = b + 1;	// <---  Oops!
			...
			return a;
		}
	}

Because I forgot to declare 'a', I end up overwriting a base class
member which I didn't intend to change. Not good. (Furthermore, if the
class hierarchy is big, I may not find out about this until much later
-- I may not even be aware that some superclass declares 'a'.)


T

-- 
Without geometry, life would be pointless. -- VS


More information about the Digitalmars-d mailing list