Naked dot - accessing object fields through unqualified

Derek Foster vapor1 at teleport.com
Fri Apr 3 00:04:18 PDT 2009


Replies inline.

-----Original Message-----
>From: Reinier Zwitserloot <reinier at zwitserloot.com>
>Sent: Mar 31, 2009 9:03 AM
>To: Derek Foster <vapor1 at teleport.com>
>Cc: coin-dev at openjdk.java.net
>Subject: Re: Naked dot - accessing object fields through unqualified "." [C1]
>
>'Self-assignment is forbidden' would not be backwards compatibile.  
>Yes, such code would most likely be a bug, but its still an issue. It  
>would have to be a warning, at best.

Personally, I think it should be an error, since there seems to be no valid reason to do it, and it almost certainly indicates a bug. I think that compilers should default to being in a 'strict' mode where things like this that have been found to be bad ideas with virtually no upside are treated as illegal, even if that makes them not fully backwards compatible. For backwards compatibility, there could be a command-line switch to turn off strict mode if necessary for compiling old code.

Some other things I'd like to see in this category:

* Having an abstract class with a constructor that has 'public' or 'private' access.

* Using C-style array declarations. (int x[] instead of int[] x)

I could probably think of a few more.

>However:
>
>Every single external java compiler I know of will warn you when you  
>self-assign. Eclipse does it. So does netbeans. So does IDEA. So does  
>pmd. So does findbugs.

Mere warnings are not enough to stop people from doing this sort of thing, especially when the warning message is buried in 436 other warning messages about code which is less unambiguously broken than this is. (Note: I *HATE* it when people ignore compiler warnings like this, but I am speaking from experience when I say that it usually takes years to convince a company to clean up its act.) Unfortunately, I have worked for lots of companies that routinely ignore warnings.

>If you internalize the self-assignment warning, where do you stop?  
>There are literally hundreds of 'duh, that must be a bug' warnings you  
>could generate. Not all of them are as obvious, or as non-contentious,  
>as 'self assignment'. So, where do you stop? Do we use the glacial  
>nature of the language changes process to set this up?

I think that when a practice is almost always problematic, is easy to fix, and has no legitimate purpose (and/or has an easy workaround in the few cases that it is legitimate), it should be made an error (with the caveats above). I don't think that we should carry along every single design mistake in the 1.0 edition of the Java Language Standard with us until the end of time. The ability to achieve backwards compatibility is important (hence the ability to turn off strict mode I described above), but clarity of language design and preventing common errors is too. Otherwise, the amount of code which contains the error in question just keeps growing over time.

> I say: No. The  
>community has done a fine job of addressing these issues by creating  
>code checkers.

In my experience, the community, by and large, does not use code checkers. Relatively few companies do. Again, I wish it were otherwise, but the truth is that most companies assume that if something passes the checks done by the compiler, it's probably fine. Having tried to introduce them into companies a few times, I can report that most software engineers really don't want to be bothered with them (and are convinced that checkers won't find any bugs important enough to justify the time spent learning to use them and cleaning up lots of innocuous warnings just for the sake of the tool). Again, I thoroughly disagree with that philosophy, but that's what I have heard repeatedly in industry.

Also, using a code checker is often a painful experience if you are forced to use a framework written by people who don't use them.

The other issue is that every code checker checks for a different set of things. Just because your code passes your code checker's rules doesn't mean it will pass mine, or vice versa. The Sun Java compiler as of a specific version, at least, is the same for everybody.

> So, I'd instead suggest:
>Any improvements to java core in this area should focus on improving  
>the ability for external tools to integrate better. For example, a way  
>to extend @SuppressWarnings with additional keywords would be great. A  
>way to let javac auto-find (via the SPI system) 'warning/error'  
>plugins would be another fine idea. Having any kind of plugin system  
>for the official javac to give other tools a go at creating warnings  
>and errors on the AST that javac's parser is building would be good  
>already, using SPI to find these automatically is just one way of  
>doing it. I'm not sure APT is quite right for the job; I don't want to  
>litter annotations to the gist of '@ExtensivelyCheckMe' all over the  
>place.

I'm certainly in favor of making life easier for code checkers. However, checkers that don't get used are no better than ones that don't exist. Javac (or jikes, etc.) gets used every time someone compiles a program. That means it's going to have far more influence on the correctness of the majority of Java code than any other tool.

Derek

>
>
>  --Reinier Zwitserloot
>
>
>
>On Mar 29, 2009, at 04:42, Derek Foster wrote:
>
>> The major problem I have with this proposal is that it does not  
>> address the point of why I use a prefix on field names. As such, I  
>> would still continue to use a prefix even if this proposal were  
>> implemented.
>>
>> In short, I use a prefix to avoid typographical mistakes, like this  
>> one:
>>
>> void setFoo(Thing foob) { // Typo!
>>    this.foo = foo;
>> }
>>
>> This will compile, and no warnings are produced, but it ends up  
>> assigning foo to itself, which is not what was intended.
>>
>> Your proposal has exactly the same problem:
>>
>> void setFoo(Thing foob) { // Typo!
>>    .foo = foo;
>> }
>>
>> It therefore does not substitute for a field prefix, which WILL fix  
>> the problem:
>>
>> void setFoo(Thing foob) { // Typo!
>>    _foo = foo; // ERROR! Undefined variable 'foo'.
>> }
>>
>> So unless you had some way to make use of the dot prefix mandatory  
>> and the only legal way to access fields (which I would like, but  
>> which would be an extremely backwards-incompatible change that will  
>> never happen in Java), I don't see that adding an optional dot  
>> prefix helps the situation except to reduce typing in constructor  
>> and setter methods slightly.
>>
>> (Note: I would love a "self-assignment is forbidden" change to Java.  
>> If I have time after my other proposals, I might write one up.  
>> (Anyone else want to volunteer? This one is easy!) I might be  
>> willing to forego prefixes and use the "this.foo = foo" approach, or  
>> even the ".foo = foo" approach, if I was sure it wouldn't cause me  
>> to fall into the self-assignment trap.)
>>
>> Derek
>>
>>
>




More information about the coin-dev mailing list