warning ... is hidden in ...

Frits van Bommel fvbommel at REMwOVExCAPSs.nl
Sat May 3 05:25:05 PDT 2008


Derek Parnell wrote:
> On Sat, 03 May 2008 11:43:59 +0200, Frits van Bommel wrote:
> 
>>>> "Derek Parnell" <derek at psych.ward> wrote in message 
>>>> news:1pg84i0mr3ihw$.1ng68jjvixchm$.dlg at 40tude.net...
>>>>> Using dmd 2.013 I'm now getting some messages along the lines of ...
>>>>>
>>>>>  warning: class Foo Object opCmp is hidden in Foo
>>>>>
>>>>> What does this actually mean and how can I remove the warning (without
>>>>> removing the -w switch)?
> 
>  
>> Presumably your code currently looks something like:
>> ---
>> class C {
>>      int opCmp(C c) {
>>          // implementation
>>      }
>> }
> 
> Yes it does.
> 
> 
>> ---
>> If you want to get rid of the warning, try one of these:
>> ---
>> class C {
>>      /// Overrides Object.opCmp, throws if the argument is not a C.
>>      override int opCmp(Object o) {
>>          if (C c = cast(C) o)
>>              return opCmp(c);
>>          throw new Exception("Can't compare C to " ~ o.classinfo.name);
>>      }
>>      int opCmp(C c) {
>>          // implementation
>>      }
>> }
>> ---
>> or
>> ---
>> class C {
>>      override int opCmp(Object o) {
>>          if (C c = cast(C) o) {
>> 	    // implementation
>>          }
>>          throw new Exception("Can't compare C to " ~ o.classinfo.name);
>>      }
>> }
>> ---
>> The second one is essentially the inlined version of the first, but will 
>> be less efficient when the a and b in "a < b" are statically known to be 
>> instances of C.
>> And both versions assume the argument isn't null; if you want to handle 
>> null input (not sure why you would) you'll need some more checking.
> 
> OMG!!!
> 
> Firstly, this actually works! 
> 
> Secondly, WTF!!!  And how exactly is this making coding easier for people? 
> 
> It would seem that every bloody time anyone codes a method that just
> happens to be defined in Object, you need to go through this syntactially
> hurdle to do something that seems so commonly required. For example, I also
> coded 'toString' in my class, which meant that I have to now ALSO code this
> waste of space ...
> 
>      override string toString(){ return this.toString();}
> 
> This seems to be madness to me. What is it that I just not getting?

This is only required when you want to implement a method with the same 
name, but a different signature (return & parameter types). And IIRC you 
can even change that slightly (accept superclasses of the original 
parameter types and return a subclass of the original return type), but 
I'm not sure about that one[1].
In other words: this is mostly an issue with opCmp and opEquals, not 
most of the other Object methods (since those would normally keep the 
same signature in subclasses).
For toString() it shouldn't be necessary. And in fact, your example 
should produce an infinite recursion when called (you probably meant to 
use 'super.toString()').

If you want to add an overload of toString (for example, one taking a 
buffer so it doesn't have to return newly-allocated heap data) you can 
'import' the superclass method using something like 'alias 
Object.toString toString;' or 'alias super.toString toString;' (not sure 
about the latter). This should be more efficient than calling 
super.toString() since it avoids an extra call.

[1]: And if it does work, using interfaces instead of classes may fail 
because they use different pointers (to the interface vtable in the 
middle of the object, instead of the class vtable at the start).

> I want coding to be as easy as possible which means that I expect the
> compiler to do the tedious work for me. Am I expecting too much? I mean, if
> I code in MY class a method called "toString()" why does the compiler
> bother to assume that I'm somehow referring to the method in Object? 

Because toString() is assumed to exist by several standard functions, 
such as the write* family in Phobos and Stdout/Layout in Tango?


More information about the Digitalmars-d-learn mailing list