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?

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

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.

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.

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.

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.