www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - ambiguation between char[] and dchar[]

reply mandel <foo bar.com> writes:
Hi,

recently I stumbled over the problem where I call put("hello") on a library
class
but got something equivalent to this:
Test.d(158): function Test.put called with argument types:
        (char[4])
matches both:
        Test.put(dchar[])
and:
        Test.put(wchar[])

The reason is obviously that class Test implements put(char[] s) and
put(dchar[] s) but also put(wchar[] s).
Interestingly put(wchar[] s) isn't considered as ambiguous.

The simple solution would be to call put("hello"c), but it's also quite tedious.
I tend to forget is as often as the ';' behind class definitions in C++.

I think the default interpretation of an string should be char[]
as the compiler output suggests "(char[4])", but apparently doesn't care about.

The question is if it is a compiler bug?
Jul 09 2007
parent reply Oskar Linde <oskar.lindeREM OVEgmail.com> writes:
mandel skrev:
 Hi,
 
 recently I stumbled over the problem where I call put("hello") on a library
class
 but got something equivalent to this:
 Test.d(158): function Test.put called with argument types:
         (char[4])
 matches both:
         Test.put(dchar[])
 and:
         Test.put(wchar[])
 
 The reason is obviously that class Test implements put(char[] s) and
put(dchar[] s) but also put(wchar[] s).

 Interestingly put(wchar[] s) isn't considered as ambiguous.

This is a flaw in DMD's error reporting. It only reports the two first ambiguous matches. I've been confused by that before.
 The simple solution would be to call put("hello"c), but it's also quite
tedious.
 I tend to forget is as often as the ';' behind class definitions in C++.
 
 I think the default interpretation of an string should be char[]
 as the compiler output suggests "(char[4])", but apparently doesn't care about.

I agree. This issue has been on the ng several times in the past. Different suggestions has been aired such as making the file's current encoding (utf-8,utf-16,utf-32) define the preferred type for char literals, to make char literals always prefer the char[] overload. I strongly prefer making char literals always pick the char[] overload. Changing the source code encoding should not affect its behavior imho. In fact, I would like to make a suggest a slightly different fix to this problem, for D 2.0. - Make string literals be dynamic instead of static arrays. I.e. invariant char[], instead of invariant char[n]. There is no loss of function, but it will resolve several issues: 1. ambiguous overload of foo(char[]), foo(dchar[]), foo(wchar[]) 2. template function issues, such as: void foo(T)(T x) {...} foo("a"), foo("ab"), foo("abc"), foo("abcd"), foo("abcde") will all (with static array string literals) result in distinct template instantiations and object file bloat. typeof("123") == typeof("abc"), but != typeof("abcd") ? 3. array and aa-literals ["a", "aa"] // error, char[1] and char[2] incompatible ["a":"b", "aa":"bb"] // error
 The question is if it is a compiler bug?

It is by design. -- Oskar
Jul 09 2007
next sibling parent mandel <foo bar.com> writes:
Oskar Linde Wrote:

 The question is if it is a compiler bug?

It is by design.

So the question is now, who wants to write a bug report? :-)
Jul 10 2007
prev sibling next sibling parent Sean Kelly <sean f4.ca> writes:
Oskar Linde wrote:
 
 I strongly prefer making char literals always pick the char[] overload. 
 Changing the source code encoding should not affect its behavior imho.

I agree.
 In fact, I would like to make a suggest a slightly different fix to this 
 problem, for D 2.0.
 
 - Make string literals be dynamic instead of static arrays. I.e. 
 invariant char[], instead of invariant char[n].
 
 There is no loss of function, but it will resolve several issues:
 
 1. ambiguous overload of foo(char[]), foo(dchar[]), foo(wchar[])
 
 2. template function issues, such as:
 
 void foo(T)(T x) {...}
 
 foo("a"), foo("ab"), foo("abc"), foo("abcd"), foo("abcde")

I would love this, for the above reason. Currently, I tend to use forwarding functions for array routines just to avoid code bloat from static strings. Fortunately, I think the template mechanism is now smart enough to pick dynamic array specializations if you pass static arrays (it wasn't when I wrote my array routines), but that still requires: void foo(T)(T[] x) {...} Which obviously isn't always possible for template routines.
 will all (with static array string literals) result in distinct template 
 instantiations and object file bloat.
 
 typeof("123") == typeof("abc"), but != typeof("abcd") ?

That one is annoying too. Sean
Jul 10 2007
prev sibling parent reply BCS <ao pathlink.com> writes:
Reply to Oskar,

 mandel skrev:
 
 Hi,
 
 recently I stumbled over the problem where I call put("hello") on a
 library class
 but got something equivalent to this:
 Test.d(158): function Test.put called with argument types:
 (char[4])
 matches both:
 Test.put(dchar[])
 and:
 Test.put(wchar[])
 The reason is obviously that class Test implements put(char[] s) and
 put(dchar[] s) but also put(wchar[] s).
 
 Interestingly put(wchar[] s) isn't considered as ambiguous.
 

ambiguous matches. I've been confused by that before.

How about: Test.d(158): function Test.put called with argument types: (char[4]) matches at least: Test.put(dchar[]) and: Test.put(wchar[])
Jul 10 2007
next sibling parent reply Oskar Linde <oskar.lindeREM OVEgmail.com> writes:
BCS wrote:
 Reply to Oskar,
 
 mandel skrev:


 Test.d(158): function Test.put called with argument types:
 (char[4])
 matches both:
 Test.put(dchar[])
 and:
 Test.put(wchar[])



 This is a flaw in DMD's error reporting. It only reports the two first
 ambiguous matches. I've been confused by that before.

How about: Test.d(158): function Test.put called with argument types: (char[4]) matches at least: Test.put(dchar[]) and: Test.put(wchar[])

That simple change would remove the confusion. However, listing all matching overloads would be incredibly helpful at certain times. -- Oskar
Jul 10 2007
parent reply BCS <ao pathlink.com> writes:
Reply to Oskar,

 BCS wrote:
 
 Reply to Oskar,
 
 mandel skrev:
 
 Test.d(158): function Test.put called with argument types:
 (char[4])
 matches both:
 Test.put(dchar[])
 and:
 Test.put(wchar[])

first ambiguous matches. I've been confused by that before.

Test.d(158): function Test.put called with argument types: (char[4]) matches at least: Test.put(dchar[]) and: Test.put(wchar[])

matching overloads would be incredibly helpful at certain times.

except for the poor schmuck who gets 400 overloads and a 40 line scroll back buffer <G>
Jul 10 2007
parent mandel <foo bar.com> writes:
BCS Wrote:

 Reply to Oskar,
 
 That simple change would remove the confusion. However, listing all
 matching overloads would be incredibly helpful at certain times.
 

except for the poor schmuck who gets 400 overloads and a 40 line scroll back buffer <G>

Listing only two ambiguous functions is a good decision, maybe a message that there are more (also the count?) would be usefull.
Jul 10 2007
prev sibling parent reply Georg Wrede <georg nospam.org> writes:
BCS wrote:
 How about:
 
 Test.d(158): function Test.put called with argument types:
 (char[4])
 matches at least:

This change would be small, but it would be immensely helpful. The current error reporting gives the (possibly subliminal, but still as misleading) impression that there is *exactly one* ambiguity. But counting or enumerating all the possible matches is, IMHO, not worthwhile, /especially/ with the above change. The first ambiguity coupled with "at least" should be enough to point the programmer well into the right directon. Still, if Walter decides it is *trivial to implement a realiably comprehensive* (as in no omissions, ever) list, then ok, do it. But either "the first only" or "all", never "found these" and just when the beginning programmer learns to rely upon the list, suddenly there are a lot more matches that didn't get reported this particular time. That only confuses and p***** off people.
Jul 11 2007
parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Georg Wrede wrote:
 BCS wrote:
 How about:

 Test.d(158): function Test.put called with argument types:
 (char[4])
 matches at least:

This change would be small, but it would be immensely helpful. The current error reporting gives the (possibly subliminal, but still as misleading) impression that there is *exactly one* ambiguity. But counting or enumerating all the possible matches is, IMHO, not worthwhile, /especially/ with the above change. The first ambiguity coupled with "at least" should be enough to point the programmer well into the right directon. Still, if Walter decides it is *trivial to implement a realiably comprehensive* (as in no omissions, ever) list, then ok, do it. But either "the first only" or "all", never "found these" and just when the beginning programmer learns to rely upon the list, suddenly there are a lot more matches that didn't get reported this particular time. That only confuses and p***** off people.

I think the ideal would be for it to list the first 5 or so, then say ... "and N others" if there are more. 5 would cover most common cases, and still not completely fill up your scrollback buffer for the unusual cases.
Jul 11 2007